高级数据库设计 - 什么是执行以下操作的最有效方法

时间:2010-01-08 02:45:59

标签: php mysql database database-design

我对想法很满意,但由于我有限的编程经验,我有时会为给定的概念提出最有效的解决方案。 目前,我的想法是尝试探索引用特定于数据类型的数据库表的最有效方法。

概念

我正在构建一个管理界面,允许网站所有者根据选定的内容“容器”“构建”内容集。接口当前包含各种sql数据类型,例如int,varchar,text等,并允许用户选择数据类型,标记它,然后将它们链接到一个组中。

然后将该组作为数据集的实例引用,并可以重复使用。例如,容器'title'和'body'可用于构建一个简单的页面,该组的每个新实例都可以是一个新页面。

问题

我遇到的问题是以最有效的方式引用这些容器。我不能简单地拥有一个具有实例ID和容器ID的表,因为无法知道它们的容器类型。 例如,content-varchar表有一个id字段,然后是一个varchar格式的value字段。内容文本表有一个id字段,然后是一个文本格式的值字段。

我想过制作一个包含每种可能类型数据的大型表,但这会浪费太多空间。 目前,我知道数据类型后,我使用子查询从相关表中选择特定值,但必须有更好的解决方案。

您有什么想法/建议?

4 个答案:

答案 0 :(得分:3)

你在无用的低水平做事。

你正在以艰难的方式重塑关系数据库。在关系数据库中。

您无法将每个小块数据有效地作为强类型关系数据进行管理。

一种选择是使用更高级别的结构(不是单个字符串,而是将多个事物绑定在一起的复合记录)。

另一种选择是仅使用文本。它更简单。最终,当HTML被发送回浏览器时,它们都变成了文本。


“...各种sql数据类型,例如int,varchar,text等,并允许用户选择数据类型,标记它,然后将它们链接到一个组中。”

一组简单类型==行。允许用户根据数据类型集合自由定义表 - 好吧 - 你让他们成为程序员。你正在为桌面设计创建一个前端。

顺便说一下,很多工具已经为你做了这个。 RoR和Django浮现在脑海中:你在数据库中定义一行,在页面上定义这些元素的模板和查看如何获取行并将其与页面匹配的查看函数。

或者

使用字段标签和组标签标记简单的单个文本字段。更简单。只需用两个键发短信。您可以获取“组”并使用标签/值对填充模板。在Django中,这是一行代码来获取行,将它们转换为字典并将其传递给模板。

答案 1 :(得分:1)

以下是MySQL manual关于TEXT和BLOB字段的说法:

  

在大多数方面,您可以将BLOB列视为VARBINARY列,可以根据需要大小。同样,您可以将TEXT列视为VARCHAR列。

翻译:使用所有TEXT或BLOB列不会浪费空间。 MySQL将截断它不使用的内容(如在VARCHAR中)。

答案 2 :(得分:1)

除非我遗漏了什么,否则这听起来并不复杂。但它确实听起来就像是将关系数据库放在关系数据库中。这通常是错误的做事方式。

但是,如果你坚持,还有一些观察要做:

  • ContentSet定义一个或多个ContentItems。
  • ContentItem可以是几种明确定义的基本类型之一,ContentTypes。

所以,听起来你有四张桌子:

  • content_setsContentSets及其关联的元数据,例如创建每个元数据的用户,集合的标题等。
  • content_itemsContentItems,以及他们所属的ContentSet的外键。
  • content_types:可以存储在每个ContentItem中的可能类型列表。您的应用程序将强制执行每个项目中存储的数据是否正确。
  • content_groupsContentSets的实例,包含已实现的数据和ContentSet的外键,它们是实例。使用属性包/ blob /文本字段来存储数据本身。

答案 3 :(得分:1)

以下是此类实施的一个示例。我不会过分担心破坏关系数据库的意图 - 只要你有足够的理由。无论如何,这个实现只需要一个表 - 并依赖元数据和数据实时转换为所需类型。

我必须在用户自己管理的商业产品的上下文中支持用户可扩展的属性集。丢弃的替代方案包括让他们支付DBA来修改他们的数据库(太昂贵),生成实际表(太多失败模式),以及使用非关系数据库(大多数应用程序需要关系数据库 - 用于报告等)。

在此实现中,客户可扩展数据被建模为绑定到模型中可扩展表的键值对,其中用户提供的元数据描述了键及其值约束。两个属性都是varchars。这可能包含当时(十年前)所需的任何类型的数据:整数,浮点数,字符等。我认为它不能处理二进制图像,声音文件等。

类型,范围,大小写,未知值,特定值等的声明性约束由读取用户提供的元数据的触发存储过程处理。转换为适当的类型由应用程序或也读取元数据的UDF(无法记住哪些)处理。

解决方案并不快,但它非常灵活,可靠且易于使用。