所谓约束,就是不让你做某事,约束的存在,有助于程序员和用户合法合理地使用数据库。
数据类型其实就是对字段的一种约束,但是数据类型约束很单一,需要有一些额外的约束,从而更好地保证数据的合法性。
表的约束有很多,这里主要介绍如下几个:null/not null
default
comment
zerofill
primary key
auto_increment
unique key
null
该列可以为空not null
该列不可以为空例如,以下 SQL 语句可以创建一个名为 students
的表,其中包含三列,分别是 id
、name
和 age
CREATE TABLE students (
id INT NOT NULL,
name VARCHAR(50) NOT NULL,
age INT NOT NULL
);
每列都有一个 NOT NULL
约束,因此在插入新行时,这些列必须都包含一个非空值。
某一种数据会经常性的出现某个具体的值,可以在一开始就指定好一个默认值
DEFAULT
关键字,用于指定一个列的默认值。
默认值可以是任何合法的表达式,包括字面量(如字符串或数字),函数调用或子查询等。
例:
CREATE TABLE orders (
id INT NOT NULL,
item VARCHAR(50) NOT NULL,
quantity INT NOT NULL DEFAULT 1
);
在这个例子中,如果在插入新行时未提供 quantity
列的值,则该列将自动设置为 1
comment
,用于为表、列或索引添加注释或描述。注释可以用于提供更多的文档或说明,以帮助理解表、列或索引的目的或用途。
COMMENT
关键字可以在创建表或列时使用,也可以在修改表或列时使用。
例:
在创建表时添加注释:
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
表添加注释,以及为 id
、name
和 email
列添加注释。
在修改表时添加注释:
ALTER TABLE users COMMENT '这是用户表';
使用 SHOW CREATE TABLE
命令(desc
不行)可以查看表的详细信息,包括注释信息。例如:
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 TABLE 表名 ADD PRIMARY KEY (列名);
-- 删除主键
ALTER TABLE 表名 DROP PRIMARY KEY;
尽量在建表的时候就把表的主键设置好,而不是已经有数据了再使用 alter 添加或删除主键。
当一个表中单个列都不能唯一地标识一条记录时,可以使用联合主键来指定多个列组合成一个主键,以确保记录的唯一性。下面是一个使用联合主键的例子。
假设我们有一个 orders
表,用于存储客户订单的数据。每个订单由多个商品组成,因此每个订单可能有多条记录,每条记录表示一个商品。为了保证记录的唯一性,我们可以将 order_id
和 product_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_id
和 product_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);
自增长(Auto-Increment)是一种用于生成唯一标识符的技术,常用于数据库中表的主键列。在 MySQL 中,可以使用 AUTO_INCREMENT
关键字来为整数列设置自增长属性。
当将 AUTO_INCREMENT
关键字应用于表的列时,该列的值会自动递增。当插入新行时,可以不指定该列的值,MySQL 会自动为该列生成唯一的值,以确保每个记录都具有唯一标识符。
自增长的特点:
例:
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)
注意:
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`))
当我们尝试删除 orders
中 id
为 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)关系,但通常情况下,外键关系是用于建立“父-子”关系的。