我正在设计一个数据库(用于mysql),它允许新的用户定义属性到名为 nodes 的实体。
为了实现这一点,我创建了另外两个表。一个 customvars 表包含所有自定义属性和* nodes_customvars *,用于定义节点和 customvars 之间的关系,创建1..n和n ..1关系。
这是他链接到绘制的模型:Sketched database model
到目前为止一切都很好......但是我无法使用单独的ID为每个表正确处理INSERT和UPDATE。
例如,如果我在为特定节点插入的* nodes_customvars *表中有一个名为 color 的自定义属性,如果我尝试“INSERT ... ON DUPLICATE KEY UPDATE“它将始终插入或始终更新。
我考虑过删除* nodes_customvars *表中的“ID”字段,并使用节点 id 和 customvars id ,但我不确定这是否是最佳解决方案......
我已经阅读了这篇文章以及评论:http://weblogs.sqlteam.com/jeffs/archive/2007/08/23/composite_primary_keys.aspx
最佳解决方案是什么?
编辑:
补充:我不知道* nodes_customvars * id ,只有节点 id 和 customvars ID 即可。分析* nodes_customvars *表:
1-如果我在此表中创建节点 id 和/或 customvars id UNIQUE,则使用“ INSERT ... ON DUPLICATE KEY UPDATE“将始终更新。由于多个节点可以共享相同的 customvar ,这是错误的;
2-如果我没有创建任何UNIQUE键,“INSERT ... ON DUPLICATE KEY UPDATE”将始终INSERT,因为在语句中找不到任何UNIQUE键...
答案 0 :(得分:0)
您当前的实体设计会破坏1NF。这意味着您的架构可能会错误地存储重复数据。
nodes_customvars
描述了nodes
和customvars
之间的多对多关系。这种类型的表有时被称为辅助表,因为它的内容纯粹是从基表派生的(在本例中是节点和customvars)。
描述多对多关系的辅助表的PK应该是一个复合键,以防止重复。基本上是1NF。
桌子上的任何PK本质上都是独一无二的。无论是单个还是复合键。因此,在某些方面,您的问题没有意义,因为您正在谈论在id
和nodes
的{{1}}上打开/关闭UNIQUE约束。如果您的customvars
实际上是PK,则无法执行此操作。
那你到底想要实现什么?
答案 1 :(得分:0)
您可以通过两种方式解决“INSERT ... ON DUPLICATE KEY”的特定问题,或者按照您的描述随时插入或更新。
使用nodeId和customvarId将主数据库更改为复合键(如SyntaxGoonoo所示,并在您的问题中作为可能的选项)。
使用nodeId和customvarId添加复合唯一索引。
CREATE UNIQUE INDEX IX_NODES_CUSTOMVARS ON NODES_CUSTOMVARS(nodeId, customvarId);
这两个选项都允许“INSERT ... ON DUPLICATE KEY”功能按您的要求工作(如果不存在nodeId和customvarId的唯一组合,则INSERT;如果存在则更新)。
关于是否具有复合主键或具有附加唯一索引的单独主键列的问题,设计中需要考虑很多事项。您正在使用1NF注意事项和数据库平台的物理特性以及您正在使用的ORM的首选项(如果有)。鉴于InnoDB二级索引的工作方式(参见:http://dev.mysql.com/doc/refman/5.0/en/innodb-index-types.html的最后一段),我建议您保留现有设计,并添加额外的唯一索引。
HTH,
-Dipin