数据库设计 - 哪个更好?

时间:2013-10-01 08:41:36

标签: mysql database database-design

我有多张桌子。

它们都包含以下字段:

item_title | item_description | item_thumbnail | item_keywords

使用额外的item_type字段,然后加入相应的表,或者将它们全部保存在单独的表中,我会更好吗?

9 个答案:

答案 0 :(得分:3)

取决于具体情况。如果你的物品几乎没有区别,并且你某些你将不会在6个月,12个月,2年内需要分开物品的情景,那么就去一个通用的路线“项目”表。如果特定项类型 具有特定要求,则可以创建包含此数据的单独表,并在查询时创建LEFT JOIN以包含额外数据。

我还建议查看其他数据库类型。从你的场景来看(很多项目类型,存储的数据差异很小)我认为你可能会受益于基于文档的数据库引擎,如MongoDB,而不是基于数据的关系型数据库引擎,如MySQL。

答案 1 :(得分:3)

好的,所以表共享字段。他们是否也共享约束 1

  • 如果是,请继续合并。
  • 如果没有,您可以将它们分开,可以将它们合并在一起,具体取决于您愿意做出何种权衡。

例如,如果表具有单独的外键,您可以将它们分开,或者可以将它们合并到一个表中,但保持FK分开:

item_title
item_description
item_thumbnail
item_keywords
table1_id REFERENCES table1 (table1_id)
table2_id REFERENCES table2 (table2_id)
...
CHECK (
    (table1_id IS NOT NULL AND table2_id IS NULL ...)
    OR (table1_id IS NULL AND table2_id IS NOT NULL ...)
    ...
)

(注意:MySQL不强制执行CHECK,因此您需要从触发器或客户端代码执行等效的强制执行,或者如果可以,则使用不同的DBMS。)

我需要了解有关您的数据库的更多信息,以确定哪个更好。

  

使用额外的item_type字段,然后加入相应的表

从不在代码中强制执行FK,如果可以的话。即使您将表合并在一起,也不要合并FK,而是执行类似上面的操作。在并发环境的上下文中执行代码中的FK(多个客户端可以尝试同时修改相同的数据)很难正确并且具有良好的性能 - 让它更好DBMS为您做到了。

是的,什么是item_keywords?它是一个逗号分隔的关键字列表(或类似的),您需要进一步规范化并将关键字提取到他们自己的单独表中。


1 域(数据类型和CHECK),键(PRIMARY KEY和UNIQUE)和参考(FOREIGN KEY)约束。

答案 2 :(得分:1)

我认为尽可能减少赌桌是件好事。它易于维护。很难想象如果你有3000种item_type。然后,将有3,000个不同的表。因此,在您的情况下,单个表对我来说是个好主意。将来,当您遇到需要分离表格的情况时,您可以轻松地这样做。

简短回答,

答案 3 :(得分:0)

如果我理解得很清楚,您只需要规范化您的架构:

项目:

item_id
item_name
item_description

items_types

item_id
type_id

类型

type_id
item_file_name

因此,您可以使用任意数量的项目

这是你想做的吗?

答案 4 :(得分:0)

我建议您使用一个表用于项目,一个表用于类型,原因如下(假设有10种类型)。

  1. 我不确定您使用的是哪种编程语言。作为Java开发人员,如果我有多个表,我将不得不为每种类型创建每个实体类。所以我宁愿只有一个类,并且有一个类型作为属性。
  2. 当您必须在同一页面中显示所有类型时,您必须从10个类型的所有10个表中执行选择查询。
  3. 当您引入新类型时,您必须为CRUD和业务特定操作编写代码。开发人员将继续为每种新类型添加代码。
  4. 基本上,如果您有一个表项和一个表类型,您不必更改您引入的每个新类型的数据库模式和代码。但是如果你确定,类型的数量较少而且不会改变,你可以考虑使用多表。

答案 5 :(得分:0)

创建两个单独的表,并根据您所需的输出连接它们。

即>

1.1'st TABLE(主表==> item_type)

ITEM_TYPE(item_type_id,ITEM_TYPE_NAME,状态)

2.2'nd TABLE(子表==> item_details)

item_details(ITEM_ID,item_type_id,ITEM_TITLE,ITEM_DESCRIPTION,item_thumbnail,item_keywords)

See more examples..

答案 6 :(得分:0)

我觉得signle table会更合适。它将避免更多的连接,程序(代码)中的复杂性和多个表的比较中的错误。从数据库聚类等管理角度来看,它甚至会更好。

答案 7 :(得分:0)

如果您有这么多表需要具有相同的重复列,那么是的,这是为公共字段创建单独表的好方法。如果这些重复的列不是固定的,可以更有效,并且可以像在常用默认列的列表中再添加一列一样进行更改。

那你怎么能这样做?

我们的想法是创建一个单独的表并将常用的默认列放在那里。 该表就像一个虚拟表,即可以根据需要添加/删除列。

例如 -

- DefaultFields

- item_title | item_description | item_thumbnail | item_keywords

然后,您还可以在DefaultFields表中动态插入值,如下所示:

"INSERT INTO DefaultFields (item_table, item_title , item_description,item_thumbnail ,item_keywords) VALUES('"+ field.item_table + "','" + field.item_title + "','" + field.item_description+ "','" + field.item_thumbnail  + "','" + field.item_keywords)");

注意:字段是将值保存在表格式循环中的对象。

然后,您可以更改表格以从DefaultFields表创建这些默认字段,如:

  "ALTER TABLE " + item_table+ " ADD COLUMN [" + field.item_title + "] Text"

可以对每个表重复此操作以根据需要进行更改。

在这种设计模式中,即使你想:

1)再添加一列或

2)删除现有列或

3)更改预先存在的列名

然后您可以在虚拟表中执行此操作,其余部分由相应表中的ALTER表命令更新。

答案 8 :(得分:-1)

在我看来......我会说不,永远不会。

有两个原因:

  • 您真的想在数据库中保留逻辑含义。现在,你很清楚它是如何组织起来的。但在两个月(或一年)内,它会如此明显吗?如果有人加入该项目,他是否更容易理解您的应用程序的不同逻辑块是否分开?我的意思是......人类和猫都是动物。将它们存储在同一个盒子中仍然是合乎逻辑的吗?

  • 性能。表越短,您的请求就越快。数据仍将占用磁盘上的空间。我不会谈论知道您正在寻找哪种类型的项目的比较。我的意思是,如果您想选择应用程序的所有页面,只需比较两个请求:

多个表:

Select * from pages_tbl;

单桌:

Select * from item_tbl where type = 'page';

您将从这个设计中获得什么?没有性能,没有磁盘空间,没有可读性。我真的没有看到它的充分理由。