我正在使用Postgres数据库设计一个具有相当复杂的表格设计的应用程序,并且我坚持一点,我希望有人可以提供有关的建议。
我有几个表,每个表都有一个功能ID(或fid)。不同类型的实体具有不同的属性模式,因此我必须为每种类型创建不同的表。但是,我想确保fids在所有实体类型中都是唯一的。
如果我有三种实体类型,Entity1 / 2/3,由以下3个表表示:
Entity1 Entity2 Entity3
fid fid fid
attribute1 attribute2 attribute3
如何确保系统中的任何地方都没有重复的fid?
谢谢!
答案 0 :(得分:5)
PostgreSQL(和Oracle就此而言)使用名为Sequences的对象来生成顺序值。与MySQL和SQL Server的顺序值生成方法不同,序列不依赖于表。因此,您可以定义单个序列(documentation link):
CREATE SEQUENCE your_seq
这将创建一个名为your_seq
的序列,它将从1开始并在每次检索下一个值时递增1 - 如果要设置最小值和增量值/等,请参阅文档链接
要使用它,任何INSERT语句都需要包括:
NEXTVAL('your_seq')
...在INSERT语句中的位置填充相应的列。 IE:
INSERT INTO entity1
(fid)
VALUES
(NEXTVAL('your_seq'))
并且,为了使这一点自动化,您可以将NEXTVAL('your_seq')
设置为使用它的所有表的默认值。
答案 1 :(得分:0)
我建议您使用guids作为您的fid字段。通过这种方式,您可以确保不会出现重复的fid,并且比以下任何一种都更优雅(i)在某处保持“最高fid”并在每次执行插入操作时查询它,或者(ii)将代码放入其中每次进行插入操作时都会检查所有表中的所有fid。
答案 2 :(得分:0)
听起来像Watsuimoto和MkV正在考虑类似的东西 - 有一个基表持有FID和一些特定的实体表继承。 Watsuimoto提到它不起作用......如果你可以让它工作,那么我同意你们两个这是正确的解决方案。并且可能在整数ID上用FK模拟它并不足以帮助Watusimoto的客户将两个实体分配给同一个EntityBase。
可能的解决方法是使用实体类型的复合键来帮助识别它。一个例子:
EntityTypes EntityBase Entity1 Entity2
------------- ------------ --------- ---------
TypeName (PK) EntityID ID ID
EntityType EntityType EntityType
CommonAtts Attribute1 Attribute2
FID
Constraints:
-----------------------------------------------------------------
EntityBase:
PK... lots of options. Probably PK(EntityID, EntityType)
UNIQUE(FID)
FK(EntityType) on EntityTypes(TypeName)
Entity1 :
PK(ID) (or PK(ID, EntityID))
EntityType NOT NULL
CHECK(EntityType = "Entity1") (e.g., it is constant)
FK(EntityType) on EntityTypes(TypeName)
FK(ID, EntityType) on EntityBase (ID, EntityType)
Entity2 : <Ditto>
你在这里有很多灵活性。您可以设置每种类型的FID。您可以使EntityID在每个类型中都是唯一的,或者在所有实体中使其唯一。您可以使EntityBase具有与EntityID分开的ID。您甚至可以使EntityType成为某种计算列,或者默认它,因此您不必为其写入值。
如果由于EntityType开销而不是你的一杯茶,那么我不情愿地提供这个:
Entity1 Entity2 Features
--------- --------- ... ----------
ID (PK) ID (PK) FID (PK, arbitrary)
Attribute1 Attribute2 Entity1ID (FK)
Entity2ID (FK)
Entity3ID (FK)
Constraints:
-----------------------------------------------------------------
Features :
One and only one EntityID is NOT NULL
喜欢将表视为“实体记录”的人通常不喜欢这种方法。对于超过六个实体而言,这是笨拙的。但 是正确的,如果需要,它允许您保留单整数行ID。
当涉及到这样的问题时,我会去Ken Downs博客并环顾四周。他对关系设计有一些很好的想法。如果我能找到他在这个主题上发表的文章,这将是我的第一个建议。 This article是我能找到的最接近的。