Primary Key约束指定了该列的值在表中必须唯一。

不同于其他约束用在特定用途,主键约束在每个表都必须使用,因为它为表的数据提供了内在的结构。这不仅让表更容易被理解,也提升了查询性能。

主键只能在创建表时指定,且后续无法通过alter table来修改。不过可以创建一个包含新主键的表,然后再迁移数据。

细节

此索引不会占用额外的磁盘空间(与二级索引不同),因为CockroachDB使用主索引来构建kv层中的表数据。更多信息查看 SQL in CockroachDB: Mapping Table Data to Key-Value Storage.

如果创建一个表而没有定义主键,CockroachDB会为每一行使用唯一标识符,然后将其用作主索引。因为你无法有意义地使用此唯一行标识符列来过滤表数据,所以它不提供任何性能优化。这意味着通过定义表的主键,你将获得更高的性能,更多信息查看:Index Selection in CockroachDB.

语法

可以在表级定义主键约束,不过,如果希望将约束应用于单个列,也可以在列级别应用该约束。

列级别

图片

Parameter Description
table_name 表名
column_name 主键列名
column_type 主键列的数据类型
column_constraints 要应用于此列的任何其他列级约束。
column_def 表中任何其他列的定义。
table_constraints 要应用的任何表级约束。

举例

> CREATE TABLE orders (
    order_id        INT PRIMARY KEY,
    order_date      TIMESTAMP NOT NULL,
    order_mode      STRING(8),
    customer_id     INT,
    order_status    INT
  );

表级别

图片

Parameter Description
table_name 表名
column_def 表中任何其他列的定义。
name 约束名,必须在表中为,且满足identifier rules.
column_name 要用作主键的列的名称.

列出的列名的顺序会影响primary索引的结构。
table_constraints 要应用的任何表级约束。

举例

> CREATE TABLE IF NOT EXISTS inventories (
    product_id        INT,
    warehouse_id      INT,
    quantity_on_hand  INT NOT NULL,
    PRIMARY KEY (product_id, warehouse_id)
  );

用法示例

> CREATE TABLE IF NOT EXISTS inventories (
    product_id        INT,
    warehouse_id      INT,
    quantity_on_hand  INT NOT NULL,
    PRIMARY KEY (product_id, warehouse_id)
  );

> INSERT INTO inventories VALUES (1, 1, 100);

> INSERT INTO inventories VALUES (1, 1, 200);
pq: duplicate key value (product_id,warehouse_id)=(1,1) violates unique constraint "primary"
> INSERT INTO inventories VALUES (1, NULL, 100);
pq: null value in column "warehouse_id" violates not-null constraint

See Also