【MySQL】(3)约束

文章目录

  • 表的约束
    • 空属性
    • 默认值
    • 列描述
    • zerofill
    • 主键
      • 概念
      • 使用 alter 添加和删除主键
      • 联合主键
      • 如何设计主键
    • 自增长
    • 唯一键
    • 外键

表的约束

所谓约束,就是不让你做某事,约束的存在,有助于程序员和用户合法合理地使用数据库。

数据类型其实就是对字段的一种约束,但是数据类型约束很单一,需要有一些额外的约束,从而更好地保证数据的合法性。

表的约束有很多,这里主要介绍如下几个:null/not null default comment zerofill primary key auto_increment unique key

空属性

  • null 该列可以为空
  • not null 该列不可以为空
  • 数据库字段默认都是可以为空的,但是实际开发时,会约束某些字段不能为空,以保证这些字段能够参与运算。

例如,以下 SQL 语句可以创建一个名为 students 的表,其中包含三列,分别是 idnameage

CREATE TABLE students (
  id INT NOT NULL,
  name VARCHAR(50) NOT NULL,
  age INT NOT NULL
);

每列都有一个 NOT NULL 约束,因此在插入新行时,这些列必须都包含一个非空值。

【MySQL】(3)约束_第1张图片

默认值

某一种数据会经常性的出现某个具体的值,可以在一开始就指定好一个默认值

DEFAULT 关键字,用于指定一个列的默认值。

默认值可以是任何合法的表达式,包括字面量(如字符串或数字),函数调用或子查询等。

CREATE TABLE orders (
  id INT NOT NULL,
  item VARCHAR(50) NOT NULL,
  quantity INT NOT NULL DEFAULT 1
);

在这个例子中,如果在插入新行时未提供 quantity 列的值,则该列将自动设置为 1

【MySQL】(3)约束_第2张图片

列描述

comment ,用于为表、列或索引添加注释或描述。注释可以用于提供更多的文档或说明,以帮助理解表、列或索引的目的或用途。

COMMENT 关键字可以在创建表或列时使用,也可以在修改表或列时使用。

  1. 在创建表时添加注释:

    CREATE TABLE users (
      id INT NOT NULL COMMENT '用户ID',
      name VARCHAR(50) NOT NULL COMMENT '用户名',
      email VARCHAR(255) NOT NULL COMMENT '电子邮件',
      PRIMARY KEY (id)
    ) COMMENT '用户表';
    

    在这个例子中,COMMENT 关键字被用于为整个 users 表添加注释,以及为 idnameemail 列添加注释。

  2. 在修改表时添加注释:

    ALTER TABLE users COMMENT '这是用户表';
    

使用 SHOW CREATE TABLE 命令(desc 不行)可以查看表的详细信息,包括注释信息。例如:

【MySQL】(3)约束_第3张图片

zerofill

ZEROFILL 是一个列属性,用于在显示整数时填充前导零。

当列定义为 ZEROFILL 时,如果列中的值不足指定的位数,则在数字前面添加零以填充空白。这可以使数字在输出中对齐,以便更容易地读取和比较。

CREATE TABLE users (
  id INT(5) ZEROFILL NOT NULL,
  name VARCHAR(50) NOT NULL,
  PRIMARY KEY (id)
);

在这个例子中,id 列被定义为 INT(5) ZEROFILL,意味着它是一个整数列,最多有 5 个数字,并且在数字前填充前导零。例如,如果插入 id=1 的行,则在输出时会显示为 00001。同样,如果插入 id=123 的行,则在输出时会显示为 00123

注意,使用 ZEROFILL 属性只会在输出时填充前导零,而不会影响存储在列中的实际值。因此,在插入或更新行时,必须确保提供正确的整数值,而不是包含前导零的字符串值。

int 后的 () 里的数字就是专门为 zerofill 服务的,如果没有 zerofill,那么 () 里的数字是没有意义的。

主键

概念

在关系型数据库中,主键(Primary Key)是一种用于唯一标识表中每行记录的特殊列或集合。主键的值必须在表中是唯一的,并且不能为空。

也就是说,一张表最多只能有一个主键,而一个主键可以有多个列,这种主键也叫联合主键(Composite Primary Key),也就是将多个列作为一个主键来唯一标识一张表中的每个记录。

CREATE TABLE users (
  id INT NOT NULL AUTO_INCREMENT,
  name VARCHAR(50) NOT NULL,
  email VARCHAR(255) NOT NULL,
  PRIMARY KEY (id) -- 写法1:PRIMARY KRY(列名)
);
CREATE TABLE users (
  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, -- 写法2:直接写在约束列表
  name VARCHAR(50) NOT NULL,
  email VARCHAR(255) NOT NULL,
);

id 列定义为一个自增的整数列,它是表 users 的主键。因此,每行记录都有一个唯一的 id 值,可以通过该值来标识该行。PRIMARY KEY 关键字用于指定 id 列作为主键。

AUTO_INCREMENT 是用于指定一个整数列为自增列的关键字。当在表中插入一条新记录时,MySQL 会自动为这个自增列分配一个唯一的值,该值会比上一条记录的值大 1。这样,每个新插入的记录都有一个唯一的标识符,防止出现重复值,通常用于表的主键列。

主键的作用是在表中唯一标识每行记录,使得每行记录都可以轻松地进行增、删、改、查操作。主键还可以用于定义表之间的关系,例如外键约束。另外,主键还可以用于提高查询性能,因为 MySQL 在查询主键时可以使用索引,从而更快地查找和检索数据。这些将在后面的内容中详细讲解。

使用 alter 添加和删除主键

-- 添加主键
ALTER TABLE 表名 ADD PRIMARY KEY (列名);

-- 删除主键
ALTER TABLE 表名 DROP PRIMARY KEY;

尽量在建表的时候就把表的主键设置好,而不是已经有数据了再使用 alter 添加或删除主键。

联合主键

当一个表中单个列都不能唯一地标识一条记录时,可以使用联合主键来指定多个列组合成一个主键,以确保记录的唯一性。下面是一个使用联合主键的例子。

假设我们有一个 orders 表,用于存储客户订单的数据。每个订单由多个商品组成,因此每个订单可能有多条记录,每条记录表示一个商品。为了保证记录的唯一性,我们可以将 order_idproduct_id 两列作为联合主键,这样每个订单中的商品组合就是唯一的。

CREATE TABLE orders (
  order_id INT NOT NULL,
  product_id INT NOT NULL,
  quantity INT NOT NULL,
  price DECIMAL(10,2) NOT NULL,
  PRIMARY KEY (order_id, product_id)
);

在上面的语句中,我们指定了 order_idproduct_id 两列组合成一个主键,这样每个订单中的商品组合就是唯一的。在插入数据时,我们需要同时指定这两列的值:

INSERT INTO orders (order_id, product_id, quantity, price)
VALUES (1001, 1, 2, 19.99);

INSERT INTO orders (order_id, product_id, quantity, price)
VALUES (1001, 2, 1, 29.99);

INSERT INTO orders (order_id, product_id, quantity, price)
VALUES (1002, 1, 3, 19.99);

INSERT INTO orders (order_id, product_id, quantity, price)
VALUES (1002, 3, 2, 49.99);

如何设计主键

  1. 结合业务,选择一个唯一的列属性作为主键
  2. 特定设计一个与业务无关列(如:id)

自增长

自增长(Auto-Increment)是一种用于生成唯一标识符的技术,常用于数据库中表的主键列。在 MySQL 中,可以使用 AUTO_INCREMENT 关键字来为整数列设置自增长属性。

当将 AUTO_INCREMENT 关键字应用于表的列时,该列的值会自动递增。当插入新行时,可以不指定该列的值,MySQL 会自动为该列生成唯一的值,以确保每个记录都具有唯一标识符。

自增长的特点:

  • 自增长的列必须是整数类型
  • 列必须是一个键(Key)或一部分键,通常是主键(Primary Key)或唯一键(Unique Key),以确保每个值都是唯一的。
  • 一张表最多只能有一个自增长

CREATE TABLE users (
  id INT NOT NULL AUTO_INCREMENT,
  name VARCHAR(50) NOT NULL,
  email VARCHAR(255) NOT NULL,
  PRIMARY KEY (id)
);

INSERT INTO users (name, email) VALUES
  ('Alice', '[email protected]'),
  ('Bob', '[email protected]'),
  ('Charlie', '[email protected]'),
  ('David', '[email protected]'),
  ('Eve', '[email protected]'),
  ('Frank', '[email protected]');
MariaDB [test_db]> select * from users;
+----+---------+---------------------+
| id | name    | email               |
+----+---------+---------------------+
|  1 | Alice   | alice@example.com   |
|  2 | Bob     | bob@example.com     |
|  3 | Charlie | charlie@example.com |
|  4 | David   | david@example.com   |
|  5 | Eve     | eve@example.com     |
|  6 | Frank   | frank@example.com   |
+----+---------+---------------------+
6 rows in set (0.00 sec)

注意

  1. 自增列的值是在当前表的最大值基础上加1,也就是说,如果你显式的插入一个1000是当前最大的值,下一个插入的值如果不指定,默认就是1001.
  2. 手动修改自增列的初始值
ALTER TABLE t1 AUTO_INCREMENT = 1000;

唯一键

唯一键(Unique Key)是一种用于保证表中某个列或列组的值唯一的约束条件。与主键类似,唯一键也可以用来标识表中的每个记录,但是它可以包含空值(NULL)。

与主键不同的是,一个表可以有多个唯一键,而每个唯一键可以包含多列。这意味着,唯一键可以由多个列组合而成,以确保这些列的组合值在表中是唯一的。

以下是一个创建带有唯一键的表的示例 SQL 语句:

CREATE TABLE users (
  id INT PRIMARY KEY,
  email VARCHAR(255) UNIQUE,
  name VARCHAR(50) NOT NULL
);

在上面的语句中,我们为 email 列设置了唯一键,以确保每个邮件地址在表中只出现一次。如果尝试插入一个已经存在的邮件地址,则会导致插入失败。

总的来说,主键和唯一键都用来保证数据行的唯一性,但主键是一种特殊的唯一键,用来唯一地标识一条数据记录

唯一键只是用于保证某些列的值唯一性的情况,如邮件地址、身份证号码等。

外键

在一个关系型数据库中,数据通常被分散到不同的表中,而这些表之间又有一些关联关系。例如,一个订单可能会包含多个产品,而每个产品的信息则存储在不同的表中。这时候就可以使用外键来约束这些表之间的关系。

外键(Foreign Key)是一种用于在关系型数据库中建立关系的机制。它用于定义主表和从表之间的关系,维护主表和从表间的约束。外键约束定义在从表上,主表必须有主键或唯一键。

通过将一个表中的列与另一个表中的主键或唯一键相对应,就可以在这两个表之间建立一个关系。当插入或更新一个表中的数据时,系统会自动检查关联的表中是否存在对应的数据,从而保持数据的一致性。如果关联表中的数据被删除,这时候会根据设置的规则,对关联表中的外键数据进行相应的操作,例如禁止删除或级联删除等等。

语法

FOREIGN KEY () REFERENCES 主表()

我们创建两个表,一个是 orders 表,包含订单的信息,另一个是 order_items 表,包含订单中每个商品的信息。这两个表的结构如下

CREATE TABLE orders (
  id INT PRIMARY KEY,
  customer_name VARCHAR(50),
  order_date DATE
);

CREATE TABLE order_items (
  id INT PRIMARY KEY,
  order_id INT,
  product_name VARCHAR(50),
  quantity INT,
  price DECIMAL(10, 2),
  FOREIGN KEY (order_id) REFERENCES orders(id)
);

在上述示例中,orders 表的主键是 id 列,order_items 表的主键是id列,同时还定义了一个外键 order_id,它与 orders 表中的 id 列相对应,用于建立 orders 表和 order_items 表之间的关系。

接下来,我们向这两个表中插入一些数据,如下所示:

INSERT INTO orders (id, customer_name, order_date)
VALUES (1, 'John Doe', '2023-01-01'),
       (2, 'Jane Smith', '2023-01-02');

INSERT INTO order_items (id, order_id, product_name, quantity, price)
VALUES (1, 1, 'Product A', 2, 10.00),
       (2, 1, 'Product B', 1, 20.00),
       (3, 2, 'Product C', 3, 30.00),
       (4, 2, 'Product D', 2, 40.00);

在上述示例中,我们向 orders 表中插入了两条数据,分别对应于编号为 1 和 2 的订单,同时向 order_items 表中插入了四条数据,分别对应于 orders 表中的两个订单中的商品。

下面演示外键约束对我们的作用

现在 orders 里面有 id 为 1、 2 的两个订单,如果我们向 order_items 里面插入一个属于 3 号订单的商品,MySQL 就会报错,因为 orders 里根本就没有 id 为 3 的订单:

MariaDB [test_db]> insert into order_items values (5, 3, 'Product E', 1, 50.00);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test_db`.`order_items`, CONSTRAINT `order_items_ibfk_1` FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`))

当我们尝试删除 ordersid 为 1 的订单,MySQL 也会向我们报错,因为在 order_items 中还有属于 1 号订单的商品。

MariaDB [test_db]> delete from orders where id=1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`test_db`.`order_items`, CONSTRAINT `order_items_ibfk_1` FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`))

表之间的关系是根据业务逻辑天然存在的,而有了外键的约束,可以有效地防止程序员后续因为逻辑错误而对表进行错误操作。确保了数据的一致性和完整性。

外键所联系的两表之间究竟是一种什么关系?

外键所连接的两个表之间通常表示一种“父-子”(Parent-Child)的关系,也称为“从属”(Dependent)关系。

在这种关系中,其中一个表(通常是拥有主键的表)被视为“父表(主表)”,而另一个表(通常是拥有外键的表)则被视为“子表(从表)”。子表中的每一行都与父表中的某一行相关联,这种关联关系由外键来维护。

例如,在一个订单管理系统中,订单(orders)表是父表,而商品详情(order_items)表则是子表。每个订单可能会包含多个商品详情,因此,商品详情表中的每一行都与订单表中的某一行相关联。

需要注意的是,外键关系不仅仅限于“父-子”关系,也可以用于表示其他类型的关系,例如“一对一”(One-to-One)关系或“多对多”(Many-to-Many)关系,但通常情况下,外键关系是用于建立“父-子”关系的。

你可能感兴趣的:(MySQL数据库,mysql,数据库,sql,后端)