06 约束

06 约束


一、约束是什么

在创建表的时候,可以给表的字段添加相应的约束,添加约束的目的是为了保证表中的数据合法性、有效性、完整性。

二、常见约束分类

  1. 非空约束(not null):约束字段不能为NULL

  2. 唯一约束(unique):约束的字段不能重复

  3. 主键约束(primary key):约束的字段既不能为NULL,也不能重复

    1. 主键的作用:

      • 表的设计三范式有要求,第一范式就要求任何一张表都应该有主键。
      • 主键是这行数据记录的唯一标识
    2. 主键分类

      • 根据主键字段数量划分:

        1. 单一主键(常用,推荐)
        2. 复合主键(多个字段联合起来添加应该主键约束)(不推荐使用,违背三范式)
      • 根据主键性质划分

        1. 自然主键:主键最好是一个与业务没有关系的自然数
        2. 业务主键:主键和系统的业务挂钩,例如:银行卡号,身份证号作为主键(不推荐使用)
  4. 外键约束(foreign key):

  5. 检查约束(check):注意:Oracle数据库支持check约束,MySQL目前不支持该约束。

三、主键的创建

  1. 使用列级约束方式定义主键

    create table t_stu(
        id int primary key,
        no int,
        name varchar(64)
    );
    
  2. 使用表级约束方式定义主键

    create table t_stu(
        id int,
        no int,
        name varchar(64),
        primary key(id)
    );
    
  3. 自然主键的创建一般联合auto_increment使用。

    create table t_stu(
        id int primary key auto_increment,
        no int,
        name varchar(64)
    );
    

四、外键约束

  1. 外键约束相关术语

    • 外键约束:foreign key
    • 外键字段:添加有外键约束的字段
    • 外键值:外键字段中的每一个值
  2. 示例

    <!-- 父表 -->
    t_class
    
    create table t_class(
        cno int,
        cname varchar(64),
        primary key(cno)
    );
    
    
    <!-- 子表 -->
    t_stu
    
    create table t_stu(
        sno int,
        sname varchar(64),
        classno int,
        primary key(sno),
        foreign key(classno) references t_class(cno)
    );
    
    insert into t_class values (100,'xxxxxxxx');
    insert into t_class values (101,'yyyyyyyy');
    insert into t_class values (102,'zzzzzzzz');
    
    insert into t_stu values (1001,'zs1',101);
    insert into t_stu values (1002,'zs2',101);
    insert into t_stu values (1003,'zs3',102);
    <!-- 错误 -->
    insert into t_stu values (1004,'zs4',109);
    
    
  3. 注意:

    1. 用外键引用的表称为‘子表’,被引用的表称为‘父表’。
    2. 引用的外键字段可以不是主键,但必须有unique约束。
    3. 子表的外键只可以是NULL。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,您的问题是如何用 SQL Server 语句实现创建一个数据库,至少有5个表,每个表至少有10条数据,至少有两个表具有外键,使用模式匹配查询,使用 top 查询,in 查询,降序查询,使用 count 集合函数查询,分组统计查询,使用连接条件的多表查询,比较运算符的子查询,使用 in 的子查询,创建视图并使用,创建索引,创建唯一性约束,检查约束,默认值约束,外键约束,创建一个存储过程并使用,在某个表上创建一个插入和更新的 DML 触发器。 以下是实现该问题的 SQL Server 语句: 创建一个名为 myDatabase 的数据库: ``` CREATE DATABASE myDatabase; GO ``` 在 myDatabase 中创建 5 个表,每个表至少有 10 条数据,其中 book 和 author 表具有外键关系: ``` USE myDatabase; GO CREATE TABLE book ( book_id INT PRIMARY KEY, book_name VARCHAR(50), author_id INT FOREIGN KEY REFERENCES author(author_id), publish_date DATE, price FLOAT ); CREATE TABLE author ( author_id INT PRIMARY KEY, author_name VARCHAR(50), author_email VARCHAR(50) ); CREATE TABLE customer ( customer_id INT PRIMARY KEY, customer_name VARCHAR(50), customer_email VARCHAR(50), customer_phone VARCHAR(20) ); CREATE TABLE order ( order_id INT PRIMARY KEY, customer_id INT FOREIGN KEY REFERENCES customer(customer_id), book_id INT FOREIGN KEY REFERENCES book(book_id), order_date DATE ); CREATE TABLE supplier ( supplier_id INT PRIMARY KEY, supplier_name VARCHAR(50), supplier_email VARCHAR(50), supplier_phone VARCHAR(20) ); INSERT INTO book VALUES (1, 'Book A', 1, '2022-01-01', 50.0); INSERT INTO book VALUES (2, 'Book B', 2, '2022-02-01', 30.0); INSERT INTO book VALUES (3, 'Book C', 3, '2022-03-01', 20.0); INSERT INTO book VALUES (4, 'Book D', 4, '2022-04-01', 40.0); INSERT INTO book VALUES (5, 'Book E', 5, '2022-05-01', 60.0); INSERT INTO book VALUES (6, 'Book F', 1, '2022-06-01', 70.0); INSERT INTO book VALUES (7, 'Book G', 2, '2022-07-01', 80.0); INSERT INTO book VALUES (8, 'Book H', 3, '2022-08-01', 90.0); INSERT INTO book VALUES (9, 'Book I', 4, '2022-09-01', 100.0); INSERT INTO book VALUES (10, 'Book J', 5, '2022-10-01', 110.0); INSERT INTO author VALUES (1, 'Author A', '[email protected]'); INSERT INTO author VALUES (2, 'Author B', '[email protected]'); INSERT INTO author VALUES (3, 'Author C', '[email protected]'); INSERT INTO author VALUES (4, 'Author D', '[email protected]'); INSERT INTO author VALUES (5, 'Author E', '[email protected]'); INSERT INTO customer VALUES (1, 'Customer A', '[email protected]', '1234567890'); INSERT INTO customer VALUES (2, 'Customer B', '[email protected]', '2345678901'); INSERT INTO customer VALUES (3, 'Customer C', '[email protected]', '3456789012'); INSERT INTO customer VALUES (4, 'Customer D', '[email protected]', '4567890123'); INSERT INTO customer VALUES (5, 'Customer E', '[email protected]', '5678901234'); INSERT INTO customer VALUES (6, 'Customer F', '[email protected]', '6789012345'); INSERT INTO customer VALUES (7, 'Customer G', '[email protected]', '7890123456'); INSERT INTO customer VALUES (8, 'Customer H', '[email protected]', '8901234567'); INSERT INTO customer VALUES (9, 'Customer I', '[email protected]', '9012345678'); INSERT INTO customer VALUES (10, 'Customer J', '[email protected]', '0123456789'); INSERT INTO [order] VALUES (1, 1, 1, '2022-01-01'); INSERT INTO [order] VALUES (2, 2, 2, '2022-02-01'); INSERT INTO [order] VALUES (3, 3, 3, '2022-03-01'); INSERT INTO [order] VALUES (4, 4, 4, '2022-04-01'); INSERT INTO [order] VALUES (5, 5, 5, '2022-05-01'); INSERT INTO [order] VALUES (6, 6, 6, '2022-06-01'); INSERT INTO [order] VALUES (7, 7, 7, '2022-07-01'); INSERT INTO [order] VALUES (8, 8, 8, '2022-08-01'); INSERT INTO [order] VALUES (9, 9, 9, '2022-09-01'); INSERT INTO [order] VALUES (10, 10, 10, '2022-10-01'); INSERT INTO supplier VALUES (1, 'Supplier A', '[email protected]', '1234567890'); INSERT INTO supplier VALUES (2, 'Supplier B', '[email protected]', '2345678901'); INSERT INTO supplier VALUES (3, 'Supplier C', '[email protected]', '3456789012'); INSERT INTO supplier VALUES (4, 'Supplier D', '[email protected]', '4567890123'); INSERT INTO supplier VALUES (5, 'Supplier E', '[email protected]', '5678901234'); ``` 使用模式匹配查询 book 表中书名(book_name)以“Book A”开头的记录: ``` SELECT * FROM book WHERE book_name LIKE 'Book A%'; ``` 使用 top 查询 book 表中价格(price)前 3 高的记录: ``` SELECT TOP 3 * FROM book ORDER BY price DESC; ``` 使用 in 查询 book 表中作者编号(author_id)为 1 或 2 的记录: ``` SELECT * FROM book WHERE author_id IN (1, 2); ``` 降序查询 book 表中价格(price): ``` SELECT * FROM book ORDER BY price DESC; ``` 使用 count 集合函数查询 book 表中记录总数: ``` SELECT COUNT(*) FROM book; ``` 分组统计查询 order 表中每个书籍(book_id)的销售总金额(price * 订单数量): ``` SELECT book_id, SUM(price * quantity) AS total_sales FROM ( SELECT order.book_id, book.price, COUNT(*) AS quantity FROM [order] JOIN book ON [order].book_id = book.book_id GROUP BY order.book_id, book.price ) AS order_detail GROUP BY book_id; ``` 使用连接条件的多表查询,查询每个订单(order_id)的书籍信息(book_name)和顾客信息(customer_name): ``` SELECT [order].order_id, book.book_name, customer.customer_name FROM [order] JOIN book ON [order].book_id = book.book_id JOIN customer ON [order].customer_id = customer.customer_id; ``` 比较运算符的子查询,查询 book 表中价格(price)高于平均价格的记录: ``` SELECT * FROM book WHERE price > (SELECT AVG(price) FROM book); ``` 使用 in 的子查询,查询 book 表中作者编号(author_id)为 1 或 2 的记录: ``` SELECT * FROM book WHERE author_id IN (SELECT author_id FROM author WHERE author_name IN ('Author A', 'Author B')); ``` 创建视图(view)用于查询每个书籍(book_id)的销售总金额(price * 订单数量): ``` CREATE VIEW book_sales AS SELECT book_id, SUM(price * quantity) AS total_sales FROM ( SELECT order.book_id, book.price, COUNT(*) AS quantity FROM [order] JOIN book ON [order].book_id = book.book_id GROUP BY order.book_id, book.price ) AS order_detail GROUP BY book_id; ``` 查询视图 book_sales: ``` SELECT * FROM book_sales; ``` 创建索引(index)用于加速 book 表的 book_name 查询: ``` CREATE INDEX idx_book_name ON book (book_name); ``` 创建唯一性约束(unique constraint)用于保证 customer 表的 customer_email 唯一性: ``` ALTER TABLE customer ADD CONSTRAINT uc_customer_email UNIQUE (customer_email); ``` 创建检查约束(check constraint)用于限制 book 表的 price 取值范围在 0 和 100 之间: ``` ALTER TABLE book ADD CONSTRAINT ck_book_price CHECK (price >= 0 AND price <= 100); ``` 创建默认值约束(default constraint)用于指定 book 表的 publish_date 默认值为当前日期: ``` ALTER TABLE book ADD CONSTRAINT df_book_publish_date DEFAULT GETDATE() FOR publish_date; ``` 创建外键约束(foreign key constraint)用于保证 order 表的 customer_id 和 book_id 在 customer 和 book 表中存在: ``` ALTER TABLE [order] ADD CONSTRAINT fk_order_customer FOREIGN KEY (customer_id) REFERENCES customer(customer_id); ALTER TABLE [order] ADD CONSTRAINT fk_order_book FOREIGN KEY (book_id) REFERENCES book(book_id); ``` 创建一个名为 myProcedure 的存储过程(stored procedure),用于查询 book 表中价格低于某个值的记录: ``` CREATE PROCEDURE myProcedure @price FLOAT AS BEGIN SELECT * FROM book WHERE price < @price; END; ``` 使用存储过程 myProcedure,查询 book 表中价格低于 50 的记录: ``` EXEC myProcedure 50; ``` 在 book 表中创建一个插入和更新的 DML 触发器(DML trigger),用于在插入或更新记录时自动更新 author 表中的作者数量(author_count): ``` CREATE TRIGGER tr_book_insert_update ON book AFTER INSERT, UPDATE AS BEGIN UPDATE author SET author_count = (SELECT COUNT(*) FROM book WHERE book.author_id = author.author_id) WHERE author.author_id IN (SELECT author_id FROM inserted UNION SELECT author_id FROM deleted); END; ``` 以上就是使用 SQL Server 语句实现创建一个数据库,至少有 5 个表,每个表至少有 10 条数据,至少有两个表具有外键,使用模式匹配查询,使用 top 查询,in 查询,降序查询,使用 count 集合函数查询,分组统计查询,使用连接条件的多表查询,比较运算符的子查询,使用 in 的子查询,创建视图并使用,创建索引,创建唯一性约束,检查约束,默认值约束,外键约束,创建一个存储过程并使用,在某个表上创建一个插入和更新的 DML 触发器的 SQL Server 语句实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值