在库存/生产系统中,我通常实现类似于以下描述的表结构......
--- Raw Item ---
id INT(10) UNSIGNED AUTO_INCREMENT,
name VARCHAR(32) NOT NULL,
description VARCHAR(128) NOT NULL,
ideal INT(10) UNSIGNED,
PRIMARY KEY(id)
另一个表格与处理过的项目具有相同的字段...
具有类似结构的客户端和提供者的下一个表。
然后是具有类似结构的收入订单和结果订单的表格。
最后,一个表格,用于确定某个已处理项目与生成批次所需的原始项目类型(有数量)之间的关系......
它表现良好......但我想知道合并类似的表并添加诸如' type'之类的字段会更好,请提供一些建议。
答案 0 :(得分:3)
在我看来,添加人工类型来组合类似的数据不是3NF。除非您需要同一个表中的数据,否则请使用单独的表。
客户和提供商有类似的字段,但它们是两个不同的东西。
如果订单从PO迁移到Processed,则它是相同的,并且具有状态标志是合适的。如果要将数据从一个表移动到另一个表,则首选与标志组合。
答案 1 :(得分:1)
这是一个很好的问题和许多SQL好问题,答案是“它取决于”。
恕我直言,可以为不同的工件(具有相似的属性)创建类似的(内部结构化表)。 见,你可以得到:
Owner
Id, Name
Pet
Id, Name
具有相同列但不同含义的表格。 当然,你可以在同一个表中获得Items和RawItens,只需要一个Flag列来区分它们。您甚至可以使用自引用FK来将项目与RamItems相关联,但这会如何影响性能?
因为你的表增长引擎需要更多时间(资源,mem,cpu)来检索行/数据。如果你将行加倍...对于大多数DBMS加倍表,不良影响性能会使表行加倍。
它也会影响进化维护。如果您现在需要为RawItems添加一列而不是为您的Items添加一列,则可能会浪费空间。
“合并”类似的表可能会增加难以理解您的架构,而不是简化它。
答案 2 :(得分:0)
我认为这会略微取决于您选择的数据库架构。有关更多信息,请参阅此链接; https://dev.mysql.com/doc/refman/5.1/en/storage-engines.html
每个人都会为您提供不同程度的性能提升和某些领域缺乏功能。我想真正的问题是你想要处理多个表,还是更容易处理单个表?
对此的一个简单解决方案是向表中添加类似状态的简单内容。然后只需更改您的查询即可对状态进行检查。非常简单,节省空间的方法将两个表保存为一个。
--- Raw Item ---
id INT(10) UNSIGNED AUTO_INCREMENT,
name VARCHAR(32) NOT NULL,
description VARCHAR(128) NOT NULL,
ideal INT(10) UNSIGNED,
status VARCHAR(9) NOT NULL,
PRIMARY KEY(id)
SELECT * from items WHERE status="PROCESSED";
我个人更喜欢这种方法。它只剩下一个库存表,而不是让多个表混乱数据库模式。更不用说它是否会进一步扩展(例如,你有新的,已处理的和存档的)。
答案 3 :(得分:0)
您将如何随时间使用这些数据?如果您需要将所有这些表组合在一起进行报告,那么如果一个表非常大,则可能更适合使用分区。如果您需要将记录从一个表移动到另一个表,因为它移动了一个进程,如果一个表都在一个表中,则更容易检查进程的状态。
此外,如果事物是非常不同的实体,它们可能具有不同的相关表格,然后将它们组合起来只会使水域混乱,使数据库更难以理解,并降低PK / FK关系的有效性。在这种情况下,单独的表格最有意义。如果您认为随着时间的推移数据会随着当前计划的功能的增加而发生分歧,那么这也是最有意义的。
以客户和销售代表为例。它们可能具有许多相同的字段,但它们相关的内容将非常不同,您不希望客户能够将其放入子表中以供代表使用。所以现在你必须提供超过FK的关系。此外,如果您有足够的子表,则会使删除记录变得困难。 db必须检查所有表,即使其中只有一半可能适用于特定记录。
在我看到的一个数据库中,原始设计师合并了两个不同的东西,但是在父级别上有相同的字段,最终在该表上有超过100个FK。从那张桌子上删除并且从不快速是一场噩梦。并且偶尔存在数据完整性问题,其中一种类型的记录最终出现在错误的子表中。