主键

定义

表中经常有一个列或多列的组合,其值能唯一地标识表中的每一行。这样的一列或多列称为表的主键,通过它可强制表的实体完整性。当创建或更改表时可通过定义 PRIMARY KEY 约束来创建主键。一个表只能有一个 PRIMARY KEY 约束,而且 PRIMARY KEY 约束中的列不能接受空值。由于 PRIMARY KEY 约束确保唯一数据,所以经常用来定义标识列。

目的

主键的一个目的就是确定数据的唯一性,它跟唯一约束的区别就是,唯一约束可以有一个NULL值,但是主键不能有NULL值,并且有以下的作用:

  • 保证实体的完整性
  • 加快数据库的操作速度
  • 在表中添加新记录时,DBMS会自动检查新记录的主键值,不允许该值与其他记录的主键值重复

特性

虽然主键不是必需的,但最好为每个表都设置一个主键,不管是单主键还是复合主键。它存在代表着表结构的完整性,表的记录必须得有唯一区分的字段,主键主要是用于其他表的外键关联,以及本记录的修改与删除。

主键选择原则

  • 最少性:在可以同时选择单一主键和组合主键(即用几列的组合来标识唯一行)时,尽管采用单一主键。
  • 稳定性:被定义为主键的列,其数据应该想对稳定,不需要经常进行更新,最好永远不会改变。

注意

建表时候必须在create table语句中指定主键,如果建表不指定主键的话,hubble数据库在建表时候自带rowid默认作为主键。

主键示例

单一主键

给一个字段建立主键,客户号cust_no唯一

create table  cust_info(
    cust_no   string primary key,
    cust_name varchar(30) not null,
    cust_card_no  varchar(18),  
    cust_phoneno  DECIMAL(15)
 );

复合主键:

多个字段建立复合主键,通过身份证号和姓名联合保证数据唯一,这是由于实际数据中姓名可以重复,但姓名与身份证的组合不会重复,能确定唯一值。

create table  cust_info_bak(
    cust_name varchar(30) not null,
    cust_card_no  varchar(18),  
    cust_phoneno  DECIMAL(15),
    primary key(cust_card_no,cust_name)   
);

更改主键

主键可以进行更改,但是在被更改的主键字段,必须在create table时候有not null进行约定,如果选用新增的字段作为主键,必须强调增加的字段语句要有not null,否则会导致主键更改失败。

CREATE TABLE cust_user (
  cust_id STRING PRIMARY KEY,
  cust_no varchar(20) ,
  cust_email STRING ,
  cust_name STRING,
  cust_addr STRING,
  cust_en STRING 
);
  • 此时cust_id为主键
show columns from cust_user;
  column_name |  data_type  | is_nullable | column_default | generation_expression |  indices  | is_hidden
--------------+-------------+-------------+----------------+-----------------------+-----------+------------
  cust_id     | STRING      |    false    | NULL           |                       | {primary} |   false
  cust_no     | VARCHAR(20) |    false    | NULL           |                       | {}        |   false
  cust_email  | STRING      |    true     | NULL           |                       | {}        |   false
  cust_name   | STRING      |    true     | NULL           |                       | {}        |   false
  cust_addr   | STRING      |    true     | NULL           |                       | {}        |   false
  cust_en     | STRING      |    true     | NULL           |                       | {}        |   false
  cust_tel    | STRING      |    false    | NULL           |                       | {}        |   false
  • 如果想用cust_no作为主键,必须做非空设置
ALTER TABLE cust_user ALTER COLUMN cust_no SET NOT NULL;
ALTER TABLE cust_user ALTER PRIMARY KEY USING COLUMNS (cust_no);
  • 增加列,并用此列作为新的主键
ALTER TABLE cust_user ADD COLUMN cust_tel string NOT NULL;
ALTER TABLE cust_user ALTER PRIMARY KEY USING COLUMNS (cust_tel);
  • 此时,主键已经更改成功,查看如下
show columns from cust_user;
  column_name |  data_type  | is_nullable | column_default | generation_expression |             indices             | is_hidden
--------------+-------------+-------------+----------------+-----------------------+---------------------------------+------------
  cust_id     | STRING      |    false    | NULL           |                       | {cust_user_cust_id_key}         |   false
  cust_no     | VARCHAR(20) |    false    | NULL           |                       | {}                              |   false
  cust_email  | STRING      |    true     | NULL           |                       | {}                              |   false
  cust_name   | STRING      |    true     | NULL           |                       | {}                              |   false
  cust_addr   | STRING      |    true     | NULL           |                       | {}                              |   false
  cust_en     | STRING      |    true     | NULL           |                       | {}                              |   false
  cust_tel    | STRING      |    false    | NULL           |                       | {cust_user_cust_id_key,primary} |   false