我正在构建一个数据库,用于记录跨多种不同媒体类型(书籍、CD、DVD 等)的集合中各个项目的极其详细的信息。集合中的每个项目都是唯一的(没有重复/多个副本),并且将具有唯一的表条目。根据媒体类型,这些条目将包含在不同的表中。我希望每个项目都有一个唯一的 ID 代码(序列号)。我正在研究如何确保每个条目都有唯一的代码,无论格式如何(因此 id = 在所有表中都是唯一的)。无论媒体类型如何,任何两个项目都不应具有相同的 ID 代码。
UNIQUE 约束仅适用于单个表,而不适用于数据库中的所有表。
关联数据非常有限的主列表可以生成唯一的 id,然后将所有媒体类型表作为子表(可能通过使用外键关联):
CREATE TABLE entrymasterlist (
masterid SERIAL UNIQUE PRIMARY KEY,
entrytitle VARCHAR(100) NOT NULL,
primarycontributer VARCHAR(100) NOT NULL,
mediatype VARCHAR(50) NOT NULL
);
但是,使用带有媒体类型表作为子表的主表将要求用户首先创建主引用,然后在相关子表中创建详细的项目条目。如果主表中的条目可以在正确的媒体类型表中自动创建匹配条目(mediatype = book 在 books 表中创建条目),并且 id 和 title 字段从主表,但必须编辑生成的条目来填写子表的更具体的数据字段(对用户来说是冗余的)仍然很笨重。
Stack Overflow 问题中有关唯一 ID 字段的最接近匹配的答案也存在依赖父表条目的相同问题,这会产生上述冗余问题。例如:所有子类型的唯一序列 ID。
有什么不同的方法可以实现项目 id 的预期结果,这些结果在媒体类型表中完全唯一且没有输入冗余?
或者我是否需要使用主表并找到一种方法来解决它或最小化它(如果不可能完全消除输入冗余)?
输入冗余不存在:每当用户添加项目时,应用程序的工作就是创建两个
INSERT
。如果您打算不使用程序来处理此问题,而是希望让最终用户在交互式数据库客户端中键入 SQL 语句,那么您就已经失败了:对于最终用户来说,SQL 太复杂且太强大(因此很危险)。
如果你想绝对保证唯一性,带有外键的主表是最好的选择。但您可以采用更简单的方法:如果您对所有表使用相同的序列,您将自动获得您想要的。不会有强制唯一性的约束,但如果你不覆盖默认值,你就会得到它。
CREATE SEQUENCE myschema.seq;
CREATE TABLE myschema.item1 (
id bigint DEFAULT nextval('myschema.seq') PRIMARY KEY,
...
);
CREATE TABLE myschema.item2 (
id bigint DEFAULT nextval('myschema.seq') PRIMARY KEY,
...
);
...