使用 UNIQUE NOT NULL 列时我真的需要 PRIMARY KEY 吗?
Do I really need PRIMARY KEY when using UNIQUE NOT NULL columns?
我在 SQL 方面的知识有限,如果有人能帮助我阐明 PRIMARY KEY
在以下情况下的用法,我将不胜感激。我创建了一个 table 来支持 ISO 国家信息。我正在使用 MariaDB 10,但我相信这与我遇到的问题无关(?)
CREATE TABLE IF NOT EXISTS python.country
(
iso_code INTEGER( 3) NOT NULL ,
iso_2_alpha VARCHAR( 2) NOT NULL ,
iso_3_alpha VARCHAR( 3) NOT NULL ,
short_name VARCHAR( 32) NOT NULL ,
long_name VARCHAR( 64) NOT NULL ,
flag_link VARCHAR(2000) DEFAULT(NULL),
CONSTRAINT CK_iso_code CHECK (iso_code > 0 AND iso_code <= 999) ,
CONSTRAINT CK_iso_alpha CHECK (
iso_2_alpha RLIKE BINARY '^[A-Z]+$' AND LENGTH(iso_2_alpha) = 2
AND
iso_3_alpha RLIKE BINARY '^[A-Z]+$' AND LENGTH(iso_3_alpha) = 3
) ,
CONSTRAINT CK_names CHECK (
short_name RLIKE '^\p{L}+(\.?[[:blank:]]\p{L}+)*\p{L}+$'
AND
long_name RLIKE '^\p{L}+(\.?[[:blank:]]\p{L}+)*\p{L}+$'
) ,
CONSTRAINT UN_short_name UNIQUE (short_name) ,
CONSTRAINT UN_long_name UNIQUE (long_name) ,
CONSTRAINT UN_iso_2_alpha UNIQUE (iso_2_alpha) ,
CONSTRAINT UN_iso_3_alpha UNIQUE (iso_3_alpha)
-- ???
-- CONSTRAINT PK_country PRIMARY KEY (iso_code,iso_2_alpha,iso_3_alpha)
); -- ENGINE = 'InnoDB';
问题 1:由于所有主要列 (iso_code
、iso_2_alpha
、iso_3_alpha
) 都是 NOT NULL
并且 UNIQUE
确实可以创建一个组合PRIMARY KEY
?我"believe"插入新元素浪费space和时间?
问题 2:我可以安全地使用 iso_code
作为其他 table 中的 FOREIGN KEY
吗?
非常感谢。
无法评论性能和效率,但复合键的一件事是当您将它们用作主键时,您必须在外键中重复它们。即,PK iso_code、iso_2_alpha、iso_3_alpha 将是所有 table 相关的附加 FK 列。然后,您还必须在 SQL 查询中按这 3 列进行查询。当您可以简单地使用通用的、唯一的自生成列时,有点像 PITA IMO。
如果您可以使用 iso_code 并且您确信您永远不会有机会要求插入具有不同 iso_2_alpha、[=16= 的副本 iso_code 】 那就继续吧。但是,您应该面向未来并使 table 更加稳健并预测意外情况,使用与业务无关的新专用 ID 列,恕我直言。
Since all main columns (iso_code,iso_2_alpha,iso_3_alpha) are NOT NULL and UNIQUE does make sense to create a composite PRIMARY KEY? I "believe" it's waste of space and time when inserting new elements?
你提议的 PK 是现有密钥的超级密钥。它本身并没有必要。您可以选择将您的唯一键约束之一声明为 PK,但这不是必需的。
Can I use iso_code safely has being the FOREIGN KEY in other table?
如果您在此 table 中也将 iso_code
标记为唯一键,那应该可以正常工作。
有些人会建议每个 table 总是有一个标记为 PK 的自动生成的列。只要您 也 强制执行逻辑键,那很好。不幸的是,许多人只会创建自动 PK 而不会创建其他密钥,这意味着您的数据是无意义的。
您已选择(目前)仅拥有逻辑键。我认为这在这种情况下很好,特别是因为几个(iso_code
、iso_2_alpha
和 iso_3_alpha
)可能比推荐的自动生成的列更紧凑。
我在 SQL 方面的知识有限,如果有人能帮助我阐明 PRIMARY KEY
在以下情况下的用法,我将不胜感激。我创建了一个 table 来支持 ISO 国家信息。我正在使用 MariaDB 10,但我相信这与我遇到的问题无关(?)
CREATE TABLE IF NOT EXISTS python.country
(
iso_code INTEGER( 3) NOT NULL ,
iso_2_alpha VARCHAR( 2) NOT NULL ,
iso_3_alpha VARCHAR( 3) NOT NULL ,
short_name VARCHAR( 32) NOT NULL ,
long_name VARCHAR( 64) NOT NULL ,
flag_link VARCHAR(2000) DEFAULT(NULL),
CONSTRAINT CK_iso_code CHECK (iso_code > 0 AND iso_code <= 999) ,
CONSTRAINT CK_iso_alpha CHECK (
iso_2_alpha RLIKE BINARY '^[A-Z]+$' AND LENGTH(iso_2_alpha) = 2
AND
iso_3_alpha RLIKE BINARY '^[A-Z]+$' AND LENGTH(iso_3_alpha) = 3
) ,
CONSTRAINT CK_names CHECK (
short_name RLIKE '^\p{L}+(\.?[[:blank:]]\p{L}+)*\p{L}+$'
AND
long_name RLIKE '^\p{L}+(\.?[[:blank:]]\p{L}+)*\p{L}+$'
) ,
CONSTRAINT UN_short_name UNIQUE (short_name) ,
CONSTRAINT UN_long_name UNIQUE (long_name) ,
CONSTRAINT UN_iso_2_alpha UNIQUE (iso_2_alpha) ,
CONSTRAINT UN_iso_3_alpha UNIQUE (iso_3_alpha)
-- ???
-- CONSTRAINT PK_country PRIMARY KEY (iso_code,iso_2_alpha,iso_3_alpha)
); -- ENGINE = 'InnoDB';
问题 1:由于所有主要列 (iso_code
、iso_2_alpha
、iso_3_alpha
) 都是 NOT NULL
并且 UNIQUE
确实可以创建一个组合PRIMARY KEY
?我"believe"插入新元素浪费space和时间?
问题 2:我可以安全地使用 iso_code
作为其他 table 中的 FOREIGN KEY
吗?
非常感谢。
无法评论性能和效率,但复合键的一件事是当您将它们用作主键时,您必须在外键中重复它们。即,PK iso_code、iso_2_alpha、iso_3_alpha 将是所有 table 相关的附加 FK 列。然后,您还必须在 SQL 查询中按这 3 列进行查询。当您可以简单地使用通用的、唯一的自生成列时,有点像 PITA IMO。
如果您可以使用 iso_code 并且您确信您永远不会有机会要求插入具有不同 iso_2_alpha、[=16= 的副本 iso_code 】 那就继续吧。但是,您应该面向未来并使 table 更加稳健并预测意外情况,使用与业务无关的新专用 ID 列,恕我直言。
Since all main columns (iso_code,iso_2_alpha,iso_3_alpha) are NOT NULL and UNIQUE does make sense to create a composite PRIMARY KEY? I "believe" it's waste of space and time when inserting new elements?
你提议的 PK 是现有密钥的超级密钥。它本身并没有必要。您可以选择将您的唯一键约束之一声明为 PK,但这不是必需的。
Can I use iso_code safely has being the FOREIGN KEY in other table?
如果您在此 table 中也将 iso_code
标记为唯一键,那应该可以正常工作。
有些人会建议每个 table 总是有一个标记为 PK 的自动生成的列。只要您 也 强制执行逻辑键,那很好。不幸的是,许多人只会创建自动 PK 而不会创建其他密钥,这意味着您的数据是无意义的。
您已选择(目前)仅拥有逻辑键。我认为这在这种情况下很好,特别是因为几个(iso_code
、iso_2_alpha
和 iso_3_alpha
)可能比推荐的自动生成的列更紧凑。