在SQL中拥有“重复字段”的最佳方法是什么?

时间:2010-01-16 20:28:32

标签: sql database-design

我正在尝试设置一个链接来自不同表的两个记录的表。这些链接本身需要与另一个表相关联。所以目前,我的表看起来像这样:

link_id    (primary key)
item_id_1  (foreign key)
item_id_2  (foreign key)
link_type  (metadata)

然而,项目之间的链接不是方向性的(即,项目是否是链接中列出的第一个或第二个项目应该没有区别)。理想情况下,我希望item_id字段只显示两次;因为它是我必须要小心,总是检查重复,以确保从未创建链接12到14的记录,如果14到12已经存在。

是否有一个优雅的数据库设计解决方案,或者我应该采用一个约定(例如id_1总是较小的ID号)和警察在应用程序中复制?

提前致谢!

3 个答案:

答案 0 :(得分:4)

您可以使用联接表。

表1:link_id(PK),link_type
JoinTable:table1_link_id,item_id(由两个id组成的复合主键)

答案 1 :(得分:1)

Benzado已经指出了 - 添加一个约束来强制执行item_id_1< item_id2:

ALTER TABLE t ADD CONSTRAINT CH_ITEM1_LESSTHAN_ITEM2 CHECK (item_id_1 < item_id_2)

因此,这将防止输入错误的数据,拒绝此类更新/插入。

如果您想在item_id_1&gt;的任何情况下自动更正它item_id_2,你可以添加一个触发器(技术上你可以同时使用它们,但是你可能会有一些麻烦让它正常工作,因为在触发器触发之前可以检查检查约束)。触发器的确切语法取决于您的RDBMS。

答案 2 :(得分:1)

有几种方法可以实现这一点。一种是检查约束和唯一约束的组合。

alter table t23 
   add constraint c1_c2_ck check (c1 < c2)
/
alter table t23 
   add constraint t23_uk unique (c1, c2)
/

这适用于大多数DBMS风格。另一种方法,至少可以在Oracle中使用,就是使用基于函数的索引....

create unique index t23_uidx on t23
    (least(c1,c2), greatest(c1,c2))
/