From fa9f124126e4526ce3db00f84372f8f01ffe8989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B7=AF=E7=8E=B2?= <1516489926@qq.com> Date: Sun, 19 Feb 2023 21:57:19 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E7=AC=AC=E4=B8=80=E6=AC=A1=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...QL\347\232\204\350\277\220\347\224\250.md" | 433 ++++++++++++++++++ 1 file changed, 433 insertions(+) create mode 100644 "29 \350\267\257\347\216\262/20230219 MySQL\347\232\204\350\277\220\347\224\250.md" diff --git "a/29 \350\267\257\347\216\262/20230219 MySQL\347\232\204\350\277\220\347\224\250.md" "b/29 \350\267\257\347\216\262/20230219 MySQL\347\232\204\350\277\220\347\224\250.md" new file mode 100644 index 0000000..adba08c --- /dev/null +++ "b/29 \350\267\257\347\216\262/20230219 MySQL\347\232\204\350\277\220\347\224\250.md" @@ -0,0 +1,433 @@ +# MySQL + +第4章 SQL语句 + +SQL:结构化查询语言,(Structure Query Language),专门用来操作/访问数据库的通用语言。 + +**4.1 SQL****的分类** + +| **名称** | **解释** | **命令** | +| --------------------- | --------------------------------------------- | ------------------------------------------------------------ | +| DDL (数据定义语言) | 定义和管理数据对象结构,如数据库,数据表等 | 创建(create),修改(alter),删除(drop) show(展示)结构 | +| DML (数据操作语言) | 用于操作数据库对象中所包含的数据 | 增(insert),删(delete),改(update) 数据 | +| DQL (数据查询语言) | 用于查询数据库数据 | 查(select) | +| DCL (数据控制语 言) | 用于管理数据库的语言,包括管理权限及数 据更改 | grant(授权),commit(确认),rollback(回滚) | + +其他语句:USE语句,SHOW语句,SET语句等。这类的官方文档中一般称为命令。 + +**4.2 SQL****语法规范** + +(1)mysql的sql语法不区分大小写 + +(2)命名时:尽量使用26个英文字母大小写,数字0-9,下划线,不要使用其他符号 + +(3)建议不要使用mysql的关键字等来作为**表名、字段名、数据库**名等,如果不小心使用,请在SQL语句中使用`(飘号/反引号)引起来,说明 : 反引号用于区别MySQL保留字与普通字符而引入的 (键盘esc下面的键) + +(4)数据库和表名、字段名等对象名中间不要包含空格 + +(5)同一个mysql软件中,数据库不能同名,同一个库中,表不能重名,同一个表中,字段不能重名 + +**4.3 SQL****脚本中如何加注释** + +SQL脚本中如何加注释 + +- 单行注释:#注释内容(mysql特有的) +- 单行注释:--空格注释内容 其中--后面的空格必须有 +- 多行注释:/* 注释内容 */ + +**4.4 mysql****脚本中的标点符号** + +mysql脚本中标点符号的要求如下: + +1. 本身成对的标点符号必须成对,例如:(),'',""。 +2. 所有标点符号必须英文状态下半角输入方式下输入。 + +几个特殊的标点符号: + +1. 小括号(): + +2. - 在创建表、添加数据、函数使用、子查询、计算表达式等等会用()表示某个部分是一个整体结构。 + - 思考: 2+3 * 6 =20 和 (2+3) * 6 =30的区别 + +3. 单引号'':**字符串和日期类型的数据值使用单引号''引起来**,数值类型的不需要加标点符号。 + +4. “2023-10--10” + +5. 双引号"":列的别名可以使用引号"",**给表名取别名不要用引号**。 + +6. 在MySQL中双引号通常等价于单引号 + +cr + +第5章 MySQL支持的数据类型 + +**5.1** **数值类型:包括整数和小数** + +数值类型主要用来存储数字,不同的数值类型提供不同的取值范围,可以存储的值范围越大,所需要的存储空间也越大。 + +对于MySQL中的数值类型,还要做如下说明: + +- 关键字INT是INTEGER的同义词。 +- 关键字DEC和FIXED是DECIMAL的同义词。 + +**5.1.1** **整数类型** + + + +**说明:** + +对于整数类型,MySQL还支持在类型名称后面加小括号(M),而小括号中的M表示显示宽度,M的取值范围是(0, 255)。int(M)这个M在字段的属性中指定了unsigned(无符号)和zerofill(零填充)的情况下才有意义。表示当整数值不够M位时,用0填充。如果整数值超过M位但是没有超过当前数据类型的范围时,就按照实际位数存储。当M宽度超过当前数据类型可存储数值范围的最大宽度时,也是以实际存储范围为准。 + +\# + +**5.1.2** **小数类型** + +MySQL中使用浮点数和定点数来表示小数。 + +浮点数有两种类型:单精度浮点数(FLOAT)和双精度浮点数(DOUBLE),定点数只有DECIMAL。浮点数和定点数都可以用(M,D)来表示。 + +- M是精度,表示该值总共显示M位,包括整数位和小数位,对于FLOAT和DOUBLE类型来说,M取值范围为0~255,而对于DECIMAL来说,M取值范围为0~65。 +- D是标度,表示小数的位数,取值范围为0~30,同时必须<=M。 + +DECIMAL实际是以字符串形式存放的,在对精度要求比较高的时候(如货币、科学数据等)使用DECIMAL类型会比较好。浮点数相对于定点数的优点是在长度一定的情况下,浮点数能够表示更大的数据范围,它的缺点是会引起精度问题。 + +**5.2** **字符串类型** + +MySQL的字符串类型有CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM、SET等。MySQL的字符串类型可以用来存储文本字符串数据,还可以存储二进制字符串。 + +文本字符串类型: + +二进制字符串类型: + +**1****、****CHAR(M)****为固定长度的字符串** + +CHAR(M)为固定长度的字符串, M表示最多能存储的字符数,取值范围是0~255个字符,如果未指定(M)表示只能存储1个字符。例如CHAR(4)定义了一个固定长度的字符串列,其包含的字符个数最大为4,如果存储的值少于4个字符,右侧将用空格填充以达到指定的长度,当查询显示CHAR值时,尾部的空格将被删掉。 + +**2****、****VARCHAR(M)****为可变长度的字符串** + +- M表示最多能存储的字符数,最大范围由字符集及M共同决定 +- M不可缺省,必须指定(M),否则报错。 +- 实际长度达不到M值时,以实际长度为准。 +- VARBINARY类型的数据除了存储数据本身外,还需要1或2个字节来存储数据的字节数。 + +c + +**使用场景**: + +- 身份证号、手机号码、QQ号、用户名username、密码password、银行卡号等固定长度的文本字符串适合使用CHAR类型; +- 评论、朋友圈、微博不定长度的文本字符串更适合使用VARCHAR类型。 + +**5.3** **日期时间类型** + +- 如果仅仅是表示年份信息,可以只使用YEAR类型,这样更节省空间,格式为“YYYY”,例如“2022”。YEAR允许的值范围是1901~2155。 +- 如果要表示年月日,可以使用DATE类型,格式为“YYYY-MM-DD”,例如“2022-02-04”。 +- 如果要表示时分秒,可以使用TIME类型,格式为“HH:MM:SS”,例如“10:08:08”。 +- 如果要表示年月日时分秒的完整日期时间,可以使用DATATIME类型,格式为“YYYY-MM-DD HH:MM:SS”,例如“2022-02-04 10:08:08”。 +- 如果需要经常插入或更新日期时间为系统日期时间,则通常使用TIMESTAMP类型,格式为“YYYY-MM-DD HH:MM:SS”,例如“2022-02-04 10:08:08”。TIMESTAMP与DATETIME的区别在于TIMESTAMP的取值范围小,只支持1970-01-01 00:00:01 UTC至2038-01-19 03:14:07 UTC范围的日期时间值,其中UTC是世界标准时间,并且TIMESTAMP类型的日期时间值在存储时会将当前时区的日期时间值转换为时间标准时间值,检索时再转换回当前时区的日期时间值,这会更友好。而DATETIME则只能反映出插入时当地的时区,其他时区的人查看数据必然会有误差的。另外,TIMESTAMP的属性受MySQL版本和服务器SQLMode的影响很大。 + +**5.4 Enum****和****Set****类型** + +无论是数值类型、日期类型、普通的文本类型,可取值的范围都非常大,但是有时候我们指定在固定的几个值范围内选择一个或多个,那么就需要使用ENUM枚举类型和SET集合类型了。 + +比如性别只有“男”或“女”;上下班交通方式可以有“地铁”、“公交”、“出租车”、“自行车”、“步行”等。 + +枚举和集合类型字段声明的语法格式如下: + +- 字段名ENUM(‘值1’,‘值2’,…‘值n’) + +- 字段名 SET(‘值1’,‘值2’,…‘值n’) + +ENUM类型的字段在赋值时,只能在指定的枚举列表中取值,而且一次只能取一个。枚举列表最多可以有65535个成员。ENUM值在内部用整数表示,每个枚举值均有一个索引值, MySQL存储的就是这个索引编号。例如,定义ENUM类型的列(‘first’, ‘second’, ‘third’)。 + +SET类型的字段在赋值时,可从定义的值列表中选择1个或多个值的组合。SET列最多可以有64个成员。SET值在内部也用整数表示,分别是1,2,4,8……,都是2的n次方值,因为这些整数值对应的二进制都是只有1位是1,其余是0。 + +**5.5** **数据字段属性** + +**unsigned** + +- 无符号的 +- 声明该数据列不允许负数 + +**ZEROFILL** + +- 0填充的 + +- 不足位数的用0来填充 , 如int(3),5则为005 + + + +5.6语法 + +§ ENGINE=InnoDB DEFAULT CHARSET=utf8 + -- 查看数据库的定义 + SHOW CREATE DATABASE school; + -- 查看数据表的定义 + SHOW CREATE TABLE student; + -- 显示表结构 + DESC student; + -- 设置严格检查模式(不能容错了) + SET sql_mode='STRICT_TRANS_TABLES'; + +# 作业 + +-- ## 第1题 +-- +-- 1、创建数据库test01_market + +```mysql +CREATE DATABASE test01_market; +USE test01_market; +-- 2、创建表格customers +create table customers( +c_num int(11), +c_name varchar(50), +c_contact varchar(50), +c_city varchar(50), +c_birth date +); +-- | 字段名 | 数据类型 | +-- | --------- | ----------- | +-- | c_num | int(11) | +-- | c_name | varchar(50) | +-- | c_contact | varchar(50) | +-- | c_city | varchar(50) | +-- | c_birth | date | +| -- **要求3:**将c_contact字段移动到c_birth字段后面 +| alter table customers modify c_contact varchar(50) after c_birth; +| -- **要求4:**将c_name字段数据类型改为 varchar(70) +| alter table customers modify c_name varchar(70); +- **要求5:**将c_contact字段改名为c_phone +| alter table customers change c_contact c_phone varchar(50); +| -- **要求6:**增加c_gender字段到c_name后面,数据类型为char(1) +| alter table customers add c_gender char(1) after c_name; +| -- **要求7:**将表名改为customers_info +alter table customers rename to customers_info; +| -- **要求8:**删除字段c_city +| alter table customers_info drop c_city; + +-- ## 第2题 +-- + +-- 1、创建数据库test02_library +create database test02_library; +use test02_library; +-- 2、创建表格books +create table books( +b_id int(11), +b_name varchar(50), +authors varchar(100), +price float, +pubdate year, +note varchar(100), +num int(11) +); +-- | 字段名 | 字段说明 | 数据类型 | 允许为空 | 唯一 | +-- | ------- | -------- | ------------- | -------- | ---- | +-- | b_id | 书编号 | int(11) | 否 | 是 | +-- | b_name | 书名 | varchar(50) | 否 | 否 | +-- | authors | 作者 | varchar(100) | 否 | 否 | +-- | price | 价格 | float | 否 | 否 | +-- | pubdate | 出版日期 | year | 否 | 否 | +-- | note | 说明 | varchar(100) | 是 | 否 | +-- | num | 库存 | int(11) | 否 | 否 | +| alter table books change hote note varchar(100); +| -- 3、向books表中插入记录 +| -- 1) 指定所有字段名称插入第一条记录 +| insert into books (b_id,b_name,`authors`,price,pubdate,note,num) VALUES (1,'Tal of AAA','Dickes',23,1995,'novel',11); +| -- 2)不指定字段名称插入第二记录 +| insert into books VALUES (2,'EmmaT','Jane lura',35,1993,'joke',22); +| -- 3)同时插入多条记录(剩下的所有记录) +| insert into books VALUES (3,'Story of Jane','Jane Tim',40,2001,'novel',0),(4,'Lovey Day','George Byron',20,2005,'novel',30),(5,'Old land','Honore Blade',30,2010,'law',0),(6,'The Battle','Upton Sara',30,1999,'medicine',40),(7,'Rose Hood','Richard haggard',28,2008,'cartoon',28); | +| DESC BOOKS; +-- | b_id | b_name | authors | price | pubdate | note | num | +-- | ---- | ------------- | --------------- | ----- | ------- | -------- | ---- | +-- | 1 | Tal of AAA | Dickes | 23 | 1995 | novel | 11 | +-- | 2 | EmmaT | Jane lura | 35 | 1993 | joke | 22 | +-- | 3 | Story of Jane | Jane Tim | 40 | 2001 | novel | 0 | +-- | 4 | Lovey Day | George Byron | 20 | 2005 | novel | 30 | +-- | 5 | Old land | Honore Blade | 30 | 2010 | law | 0 | +-- | 6 | The Battle | Upton Sara | 30 | 1999 | medicine | 40 | +-- | 7 | Rose Hood | Richard haggard | 28 | 2008 | cartoon | 28 | +| -- 4、将小说类型(novel)的书的价格都增加5。 +| UPDATE books set price = price + 5 where note='novel'; + +-- 5、将名称为EmmaT的书的价格改为40。 +update books set price = 40 where b_name = 'EmmaT'; +-- 6、删除库存为0的记录 +delete from books where num=0; + +-- ## 第3题 +-- + +-- 1、创建数据库test03_bookstore +create database test03_bookstore; +use test03_bookstore; +-- 2、创建book表 +create table book( +id int(11), +title varchar(100), +author varchar(100), +price double(11,2), +sales int(11), +stock int(11), +img_path varchar(100) +); +-- ```mysql +-- +----------+--------------+------+-----+---------+----------------+ +-- | Field | Type | Null | Key | Default | Extra | +-- +----------+--------------+------+-----+---------+----------------+ +-- | id | int(11) | NO | PRI | NULL | auto_increment | +-- | title | varchar(100) | NO | | NULL | | +-- | author | varchar(100) | NO | | NULL | | +-- | price | double(11,2) | NO | | NULL | | +-- | sales | int(11) | NO | | NULL | | +-- | stock | int(11) | NO | | NULL | | +-- | img_path | varchar(100) | NO | | NULL | | +-- +----------+--------------+------+-----+---------+----------------+ + +-- ``` +-- + +-- 尝试添加部分模拟数据,参考示例如下: +insert into book VALUES (1,'解忧杂货店','东野圭吾',27.20,102,98,'upload/books/解忧杂货店.jpg'),(2,'边城','沈从文',23.00,102,98,'upload/books/边城.jpg'); +-- ```mysql +-- +----+-------------+------------+-------+-------+-------+----------------------------+ +-- | id | title | author | price | sales | stock | img_path | +-- +----+-------------+------------+-------+-------+-------+-----------------------------+ +-- | 1 | 解忧杂货店 | 东野圭吾 | 27.20 | 102 | 98 | upload/books/解忧杂货店.jpg | +-- | 2 | 边城 | 沈从文 | 23.00 | 102 | 98 | upload/books/边城.jpg | +-- +----+---------------+------------+-------+-------+-------+----------------------------+ + +-- ``` +-- + +-- 3、创建用户表users,并插入数据 +create table users( +id int(11), +username varchar(100), +password varchar(100), +email varchar(100) +); +-- - ```mysql +-- -- +----------+--------------+------+-----+---------+----------------+ +-- -- | Field | Type | Null | Key | Default | Extra | +-- -- +----------+--------------+------+-----+---------+----------------+ +-- -- | id | int(11) | NO | PRI | NULL | auto_increment | +-- -- | username | varchar(100) | NO | UNI | NULL | | +-- -- | password | varchar(100) | NO | | NULL | | +-- -- | email | varchar(100) | YES | | NULL | | +-- -- +----------+--------------+------+-----+---------+----------------+ + +-- -- ``` +-- + +-- 尝试添加部分模拟数据,参考示例如下: +insert into users values (1,'admin',112233,'admin@mxdx.com'); +-- ```mysql +-- +----+----------+----------------------------------+--------------------+ +-- | id | username | password | email | +-- +----+----------+----------------------------------+--------------------+ +-- | 1 | admin | 112233 | admin@mxdx.com | +-- +----+----------+----------------------------------+--------------------+ + +-- ``` +-- + +-- 4、创建订单表orders +create table orders( +id varchar(100), +order_time datetime, +total_count int(11), +total_amount double(11,2), +state int(11), +user_id int(11) +); +-- ```mysql +-- +--------------+--------------+------+-----+---------+-------+ +-- | Field | Type | Null | Key | Default | Extra | +-- +--------------+--------------+------+-----+---------+-------+ +-- | id | varchar(100) | NO | PRI | NULL | | +-- | order_time | datetime | NO | | NULL | | +-- | total_count | int(11) | NO | | NULL | | +-- | total_amount | double(11,2) | NO | | NULL | | +-- | state | int(11) | NO | | NULL | | +-- | user_id | int(11) | NO | MUL | NULL | | +-- +--------------+--------------+------+-----+---------+-------+ + +-- ``` +-- + +-- 尝试添加部分模拟数据,参考示例如下: +insert into orders values (15294258455691,'2018-06-20 00:30:45',2,50.20,0,1); +-- ```mysql +-- +----------------+---------------------+-------------+--------------+-------+---------+ +-- | id | order_time | total_count | total_amount | state | user_id | +-- +----------------+---------------------+-------------+--------------+-------+---------+ +-- | 15294258455691 | 2018-06-20 00:30:45 | 2 | 50.20 | 0 | 1 | +-- +----------------+---------------------+-------------+--------------+-------+---------+ + +-- ``` +-- + +-- 5、创建订单明细表order_items +create table order_items( +id int(11), +count int(11), +amount double(11,2), +title varchar(100), +author varchar(100), +price double(11,2), +img_path varchar(100), +order_id varchar(100) +); +-- ```mysql +-- +----------+--------------+------+-----+---------+----------------+ +-- | Field | Type | Null | Key | Default | Extra | +-- +----------+--------------+------+-----+---------+----------------+ +-- | id | int(11) | NO | PRI | NULL | auto_increment | +-- | count | int(11) | NO | | NULL | | +-- | amount | double(11,2) | NO | | NULL | | +-- | title | varchar(100) | NO | | NULL | | +-- | author | varchar(100) | NO | | NULL | | +-- | price | double(11,2) | NO | | NULL | | +-- | img_path | varchar(100) | NO | | NULL | | +-- | order_id | varchar(100) | NO | MUL | NULL | | +-- +----------+--------------+------+-----+---------+----------------+ + +-- ``` +-- + +-- 尝试添加部分模拟数据,参考示例如下: +inset into order_items values (1,1,27.20,'解忧杂货店','东野圭吾',27.20,'static/img/default.jpg|15294258455691'),(2,1,23.00,'边城','沈从文',23.00,'static/img/default.jpg|15294258455691'); +-- ```mysql +-- +----+-------+--------+---------+---------+-------+----------------+----------------+ +-- | id |count| amount| title | author | price | img_path | order_id | +-- +----+-------+--------+------------+----------+-------+----------------+----------------+ +-- | 1 | 1 | 27.20| 解忧杂货店 | 东野圭吾 | 27.20 | static/img/default.jpg|15294258455691 | +-- | 2 | 1 | 23.00| 边城 | 沈从文 | 23.00 | static/img/default.jpg|15294258455691 | +-- +----+-------+--------+------------+----------+-------+------------+----------------+ +``` + +| | | | +| ---- | ---- | ---- | +| | | | +| | | | +| | | | +| | | | +| | | | +| | | | +| | | | +| | | | +| | | | +| | | | +| | | | +| | | | +| | | | +| | | | +| | | | +| | | | +| | | | +| | | | + + + -- Gitee From 049d548bbbaae5c903ab5d0f8ecb606e86fe868e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B7=AF=E7=8E=B2?= <1516489926@qq.com> Date: Wed, 22 Feb 2023 20:46:57 +0800 Subject: [PATCH 2/2] =?UTF-8?q?MySQL=E7=9A=84=E7=AC=AC=E4=BA=8C=E6=AC=A1?= =?UTF-8?q?=E4=BD=9C=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...46\346\235\237\347\273\203\344\271\240.md" | 691 ++++++++++++++++++ 1 file changed, 691 insertions(+) create mode 100644 "29 \350\267\257\347\216\262/20230222 \347\272\246\346\235\237\347\273\203\344\271\240.md" diff --git "a/29 \350\267\257\347\216\262/20230222 \347\272\246\346\235\237\347\273\203\344\271\240.md" "b/29 \350\267\257\347\216\262/20230222 \347\272\246\346\235\237\347\273\203\344\271\240.md" new file mode 100644 index 0000000..302ea2c --- /dev/null +++ "b/29 \350\267\257\347\216\262/20230222 \347\272\246\346\235\237\347\273\203\344\271\240.md" @@ -0,0 +1,691 @@ +# 约束 + +### 作业 + +```mysql +-- ## 第1题 +-- + +-- 1、创建数据库test01_company +create database test01_company charset utf8; +use test01_company; +-- 2、创建表格offices +create table offices( +officeCode int, +city varchar(30), +address varchar(50), +country varchar(50), +postalCode varchar(25) + ); + + -- 字段名 | 数据类型 | + -- -------- | ------------- | + -- officeCode | int | + -- city | varchar(30) | + -- address | varchar(50) | + -- country | varchar(50) | + -- postalCode | varchar(25) | + -- + -- 3、创建表格employees + create table employees( + empNum int(11), + lastName varchar(50), + firstName varchar(50), + mobile varchar(25), + code int, + jobTitle varchar(50), + birth date, + Note varchar(255), + Sex varchar(5) + ); +-- | | 字段名 | 数据类型 | +-- | --------- | ------------- | +-- | empNum | int(11) | +-- | lastName | varchar(50) | +-- | firstName | varchar(50) | +-- | mobile | varchar(25) | +-- | code | int | +-- | jobTitle | varchar(50) | +-- | birth | date | +-- | Note | varchar(255) | +-- | Sex | varchar(5) | | | +| -- **要求4:**将表employees的mobile字段修改到code字段后面。 +| alter table employees modify mobile varchar(25) after code; +| -- **要求5:**将表employees的birth字段改名为birthday; +| alter table employees change birth birthday date; +| -- **要求6:**修改sex字段,数据类型为char(1)。 +| alter table employees modify sex char(1); +| -- **要求7:**删除字段note; +| alter table employees drop note; +| -- **要求8:**增加字段名favoriate_activity,数据类型为varchar(100); +| alter table employees add favoriate_activity varchar(100); +| -- **要求9:**将表employees的名称修改为 employees_info +| alter table employees rename to employees_info; + +## 第2题 + +-- +-- 1、创建数据库test02db +create database test02db charset utf8; +use test02db; +-- 2、创建表格pet +create table pet( +`name` varchar(20), +`owner` varchar(20), +species varchar(20), +sex char(1), +birth year, +death year +); +-- | ------- | -------- | ----------- | +-- | name | 宠物名称 | varchar(20) | +-- | owner | 宠物主人 | varchar(20) | +-- | species | 种类 | varchar(20) | +-- | sex | 性别 | char(1) | +-- | birth | 出生日期 | year | +-- | death | 死亡日期 | year | +-- + +-- 3、添加记录 +insert into pet values +('Fluffy','harold','Cat','f',2003,2010), +('Claws', 'gwen','Cat','m',2004,null), +('Buffy', null,'Dog','f',2009,null), +('Fang','benny','Dog','m',2000,null), +('bowser','diane','Dog','m',2003,2009), +('Chirpy',null,'Bird','f',2008,null); + +-- | name | owner | species | sex | birth | death | +-- | ------ | ------ | ------- | ---- | ----- | ----- | +-- | Fluffy | harold | Cat | f | 2003 | 2010 | +-- | Claws | gwen | Cat | m | 2004 | | +-- | Buffy | | Dog | f | 2009 | | +-- | Fang | benny | Dog | m | 2000 | | +-- | bowser | diane | Dog | m | 2003 | 2009 | +-- | Chirpy | | Bird | f | 2008 | | +| desc pet; +| -- 4、 添加字段主人的生日owner_birth。 +| alter table pet add owner_birth date; +| -- 5、 将名称为Claws的猫的主人改为kevin +| update pet set owner='kevin' where name='Claws'and species='Cat'; +| -- 6、 将没有死的狗的主人改为duck +| update pet set owner='duck' where death is null and species ='Dog'; +| -- 7、 查询没有主人的宠物的名字; +| select `name` from pet where `owner` is null; +| -- 8、 查询已经死了的cat的姓名,主人,以及去世时间; +| select `name`,`owner`,death from pet where death is not null and species ='cat'; +| -- 9、 删除已经死亡的狗 +| delete from pet where species='Dog' and death is not null; +| -- 10、查询所有宠物信息 +| select * from pet; + + +## 第3题 + +-- 1、创建数据库:test03_company +create database test03_company charset utf8; +use test03_company ; +-- 2、在此数据库下创建如下3表,数据类型,宽度,是否为空根据实际情况自己定义。 +-- A. 部门表(department):部门编号(depid),部门名称(depname),部门简介(deinfo);其中部门编号为主键。 +-- create table department( +-- depid int primary key auto_increment, +-- depname char(10) not null unique key, +-- deinfo varchar(200) +-- ); +create table department( +depid int primary key auto_increment, +depname varchar(50) not null unique key, +deinfo varchar(200) not null +); +alter table department modify deinfo varchar(100); +-- B. 雇员表(employee):雇员编号(empid),姓名(name),性别(sex),职称(title),出生日期(birthday),所在部门编号(depid);其中 +-- + +-- * 雇员编号为主键; +-- * 部门编号为外键,外键约束等级为(on update cascade 和on delete set null); + +-- * 性别默认为男; +-- create table employee ( +-- empid int primary key auto_increment, +-- name varchar(10) not null, +-- sex enum('男','女') not null default '男', +-- title varchar(10), +-- birthday date, +-- depid int foreign key references department(depid) +-- ); + + create table employee( + empid int primary key auto_increment, + name varchar(50) not null, + sex enum('男','女') not null default '男', + title varchar(10), + birthday date, + depid int , + foreign key (depid) references department(depid) +); + + + + +-- C. +-- 工资表(salary):雇员编号(empid),基本工资(basesalary),职务工资(titlesalary),扣除(deduction)。其中雇员编号为主键。 +-- 3、给工资表(salary)的雇员编号(empid)增加外键约束,外键约束等级为(on update cascade 和on delete cascade) +create table salary( +empid int primary key auto_increment, +foreign key (empid) references employee(empid), +basesalary int, +titlesalary int, +deduction int +); + +-- 4、添加数据如下: +-- 部门表: +-- | 部门编号 | 部门名称 | 部门简介 | +-- | -------- | -------- | ------------ | +-- | 111 | 生产部 | Null | +-- | 222 | 销售部 | Null | +-- | 333 | 人事部 | 人力资源管理 | +insert into department values +(111,'生产部',Null), +(222,'销售部',Null), +(333,'人事部','人力资源管理'); +-- 雇员表: +-- | 雇员编号 | 姓名 | 性别 | 职称 | 出生日期 | 所在部门编号 | +-- | -------- | ---- | ---- | ---------- | ---------- | ------------ | +-- | 1001 | 张三 | 男 | 高级工程师 | 1975-1-1 | 111 | +-- | 1002 | 李四 | 女 | 助工 | 1985-1-1 | 111 | +-- | 1003 | 王五 | 男 | 工程师 | 1978-11-11 | 222 | +-- | 1004 | 张六 | 男 | 工程师 | 1999-1-1 | 222 | +insert into employee values +(1001,'张三','男','高级工程师','1975-1-1',111), +(1002,'李四','女','助工','1985-1-1',111), +(1003,'王五','男','工程师','1978-11-11',222), +(1004,'张六','男','工程师','1999-1-1',222); +-- 工资表: +-- | 雇员编号 | 基本工资 | 职务工资 | 扣除 | +-- | -------- | -------- | -------- | ---- | +-- | 1001 | 2200 | 1100 | 200 | +-- | 1002 | 1200 | 200 | NULL | +-- | 1003 | 2900 | 700 | 200 | +-- | 1004 | 1950 | 700 | 150 | +insert into salary values +(1001,2200,1100,200), +(1002,1200,200,null), +(1003,2900,700,200), +(1004,1950,700,150); + + +-- ## 第4题 +-- +-- 1、创建一个数据库:test04_school +create database test04_school charset utf8; +use test04_school; +-- 2、创建如下表格 +-- +-- 表1 Department表的定义 +-- +-- | **字段名** | **字段描述** | **数据类型** | **主键** | **外键** | **非空** | **唯一** | +-- | ---------- | ------------ | ------------ | -------- | -------- | -------- | -------- | +-- | DepNo | 部门号 | int(10) | 是 | 否 | 是 | 是 | +-- | DepName | 部门名称 | varchar(20) | 否 | 否 | 是 | 否 | +-- | DepNote | 部门备注 | Varchar(50) | 否 | 否 | 否 | 否 | +create table Department( +DepNo int(10) primary key auto_increment not null unique key, +DepName varchar(20) not null, +DepNote varchar(50) +); +-- +-- 表2 Teacher表的定义 +-- +-- | **字段名** | **字段描述** | **数据类型** | **主键** | **外键** | **非空** | **唯一** | +-- | ---------- | ------------ | ------------ | -------- | -------- | -------- | -------- | +-- | Number | 教工号 | int | 是 | 否 | 是 | 是 | +-- | Name | 姓名 | varchar(30) | 否 | 否 | 是 | 否 | +-- | Sex | 性别 | varchar(4) | 否 | 否 | 否 | 否 | +-- | Birth | 出生日期 | date | 否 | 否 | 否 | 否 | +-- | DepNo | 部门号 | int | 否 | 是 | 否 | 否 | +-- | Salary | 工资 | float | 否 | 否 | 否 | 否 | +-- | Address | 家庭住址 | varchar(100) | 否 | 否 | 否 | 否 | +create table Teacher( +Number int primary key not null unique key auto_increment, +Name varchar(30) not null, +Sex varchar(4), +Birth date, +DepNo int, +foreign key (DepNo) references Department(DepNo), +Salary float, +Address varchar(100) +); + +-- 3、添加记录 +-- +-- | **DepNo** | **DepName** | **DepNote** | +-- | --------- | ----------- | ------------------ | +-- | 601 | 软件技术系 | 软件技术等专业 | +-- | 602 | 网络技术系 | 多媒体技术等专业 | +-- | 603 | 艺术设计系 | 广告艺术设计等专业 | +-- | 604 | 管理工程系 | 连锁经营管理等专业 | +insert into Department values +(601,'软件技术系','软件技术等专业'), +(602,'网络技术系','多媒体技术等专业'), +(603,'艺术设计系','广告艺术设计等专业'), +(604,'管理工程系','连锁经营管理等专业'); + +-- | **Number** | **Name** | **Sex** | **Birth** | **DepNo** | **Salary** | **Address** | +-- | ---------- | -------- | ------- | ---------- | --------- | ---------- | ------------ | +-- | 2001 | Tom | 女 | 1970-01-10 | 602 | 4500 | 四川省绵阳市 | +-- | 2002 | Lucy | 男 | 1983-12-18 | 601 | 2500 | 北京市昌平区 | +-- | 2003 | Mike | 男 | 1990-06-01 | 604 | 1500 | 重庆市渝中区 | +-- | 2004 | James | 女 | 1980-10-20 | 602 | 3500 | 四川省成都市 | +-- | 2005 | Jack | 男 | 1975-05-30 | 603 | 1200 | 重庆市南岸区 | +insert into Teacher values +(2001,'Tom','女','1970-01-10',602,4500,'四川省绵阳市'), +(2002,'Lucy','男','1983-12-18',601,2500,'北京市昌平区'), +(2003,'Mike','男','1990-06-01',604,1500,'重庆市渝中区'), +(2004,'James','女','1980-10-20',602,3500,'四川省成都市'), +(2005,'Jack','男','1975-05-30',603,1200,'重庆市南岸区'); +-- 4、用SELECT语句查询Teacher表的所有记录。 +select * from Teacher; +``` + +## 笔记 + +**14.1 约束的作用** + +约束是为了保证数据的完整性,数据完整性(Data Integrity)是指数据的精确性(Accuracy)和可靠性(Reliability)。它是应防止数据库中存在不符合语义规定的数据和防止因错误信息的输入输出造成无效操作或错误信息而提出的。 + +数据的完整性要从以下四个方面考虑: + +- 实体完整性(Entity Integrity):例如,同一个表中,不能存在两条完全相同无法区分的记录 +- 域完整性(Domain Integrity):例如:年龄范围0-120,性别范围“男/女” +- 引用完整性(Referential Integrity):例如:员工所在部门,在部门表中要能找到这个部门 +- 用户自定义完整性(User-defined Integrity):例如:用户名唯一、密码不能为空等,本部门经理的工资不得高于本部门职工的平均工资的5倍。 + +**14.2 约束的类型** + +**1、约束类型** + +- 键约束:主键约束、外键约束、唯一键约束 +- Not NULL约束:非空约束 +- Check约束:检查约束[8.0版本支持] +- Default约束:默认值约束 + +自增是键约束字段的一个额外的属性。 + +**2、表级约束和列级约束** + +其中键约束和检查约束是表级约束,即不仅要看约束字段当前单元格的数据,还要看其他单元格的数据。 + +非空约束和默认值约束都是列级约束,即约束字段只看当前单元格的数据即可,和其他单元格无关。 + +所有的表级约束都可以在“information_schema.table_constraints”表中查看。 + +SELECT * FROM information_schema.table_constraints WHERE table_name = '表名称'; + +**3、约束和索引** + +在MySQL中键约束会自动创建索引,提高查询效率。索引的详细讲解在高级部分。 + +MySQL高级会给大家讲解索引、存储引擎等,因为高级要给大家分析SQL性能。而基础阶段先不管效率,只要能查出来就行。 + +约束和索引不同: + +约束是一个逻辑概念,它不会单独占用物理空间, + +索引是一个物理概念,它是会占用物理空间。 + +例如:字典 + +字典里面有要求,不能有重复的字(字一样,读音也一样),这是约束。 + +字典里面有“目录”,它可以快速的查找某个字,目录需要占用单独的页。 + +**14.3 非空约束** + +**1、作用** + +限定某个字段/某列的值不允许为空 + +**2、关键字:not null** + +**3、特点** + +(1)只能某个列单独限定非空,不能组合非空 + +(2)一个表可以有很多列都分别限定了非空 + +**14.4 唯一键约束** + +**1、唯一键约束的作用** + +单列唯一:用来限制某个字段/某列的值不能重复。 + +组合唯一:用来限定几个字段的值组合不能重复。 + +**2、关键字:unique key** + +**3、特点** + +(1)一个表可以有很多个唯一键约束, + +(2)每一个唯一键约束字段都会自动创建索引。 + +(3)唯一键约束允许为空 + +(4)唯一键约束也可以是复合唯一 + +(5)删除唯一键约束的索引来删除唯一键约束 + +索引名默认是字段名,复合唯一默认是第一个字段名 + +**14.5 主键约束(重要)** + +**1、主键约束的作用** + +用来唯一的确定一条记录 + +**2、关键字:primary key** + +**3、特点** + +(1)唯一并且非空 + +(2)一个表最多只能有一个主键约束 + +(3)如果主键是由多列组成,可以使用复合主键 + +(4)主键列会自动创建索引(能够根据主键查询的,就根据主键查询,效率更高) + +主键列的唯一并且非空是约束的概念,但是mysql会给每个表的主键列创建索引,会开辟单独的物理空间来存储每一个主键的目录表(Btree结构)。这样设计的意义,可以根据主键快速查询到某一行的记录。 + +(5)如果删除主键约束了,主键约束对应的索引就自动删除了。 + +**4、唯一键约束和主键约束区别** + +(1)唯一键约束一个表可以有好几个, + +但是主键约束只有一个 + +(2)唯一键约束本身不带非空限制,如果需要非空,需要单独定义。 + +主键约束不用再定义NOT NULL,自身就带非空限制。 + +```my +create table 表名称( +字段名 数据类型 primary key, + 字段名 数据类型, + 字段名 数据类型 +); +create table 表名称( +字段名 数据类型, + 字段名 数据类型, + 字段名 数据类型, + primary key(字段名) +); +(2)建表后增加主键约束(了解) +alter table 表名称 add primary key(字段列表); #字段列表可以是一个字段,也可以是多个字段,如果是多个字段的话,是复合主键 + +``` + +```mys +1、作用: +主键约束是用来唯一的标识一行记录, +或者换句话说,表中不允许出现两条无法区分的记录。 + +问?唯一键约束不就可以实现吗? +答:唯一键约束因为没有限定非空,可能出现两个NULL。 + +学号 姓名 身份证号码(唯一键) +1 张三 524265198235684255 +2 李四 524265198235684266 +3 王五 NULL +3 王五 NULL + +2、关键字:primary key +3、特点 +(1)每一个表最多只能定义一个主键约束。 +(2)主键约束,既要求唯一又要求非空 +可以看成 主键约束 = 非空约束 + 唯一键约束 +但不完全等价。 + +4、唯一键约束和主键约束的区别 +(1)唯一键约束一个表可以有好几个, +但是主键约束只有一个 +(2)唯一键约束本身不带非空限制,如果需要非空,需要单独定义。 +主键约束不用再定义NOT NULL,自身就带非空限制。 +*/ + +#建表时,指定主键约束 +create table 表名称( + 字段名 数据类型 primary key, + 字段名 数据类型 not null, + 字段名 数据类型 not null unique key, + 字段名 数据类型 not null unique key, + 字段名 数据类型 unique key, + 字段名 数据类型 unique key + 字段名 数据类型 +); + +create table 表名称( + 字段名 数据类型 , + 字段名 数据类型 not null, + 字段名 数据类型 not null unique key, + 字段名 数据类型 not null unique key, + 字段名 数据类型 unique key, + 字段名 数据类型 unique key + 字段名 数据类型, + primary key(字段名), + unique key(字段名) +); + +mysql> drop database mxdx; +Query OK, 19 rows affected (0.17 sec) + +mysql> create database mxdx; +Query OK, 1 row affected (0.01 sec) + +mysql> use mxdx; +Database changed + +#创建员工表 +create table emp( + id int primary key, + ename varchar(20) not null, + cardid char(18) unique key not null, #非空并且唯一 + tel char(11) unique key, #只是唯一,可以为空 + address varchar(100) #既可以为null,又可以重复 +); + +#查看表结构 +desc emp; +14.6 默认值约束 +1、作用 +给某个字段/某列指定默认值,当添加时或修改时,可以使用默认值。 +2、关键字:default +3、如何给字段加默认值 +(1)建表时 +create table 表名称( + 字段名 数据类型 primary key, + 字段名 数据类型 unique key not null, + 字段名 数据类型 unique key, + 字段名 数据类型 not null default 默认值, +); +create table 表名称( + 字段名 数据类型 default 默认值 , + 字段名 数据类型 not null default 默认值, + 字段名 数据类型 not null default 默认值,, + primary key(字段名), + unique key(字段名) +); + +说明:默认值约束一般不在唯一键和主键列上加 +2)建表后(了解) +alter table 表名称 modify 字段名 数据类型 default 默认值; + +#如果这个字段原来有非空约束,你还保留非空约束,那么在加默认值约束时,还得保留非空约束,否则非空约束就被删除了 +#同理,在给某个字段加非空约束也一样,如果这个字段原来有默认值约束,你想保留,也要在modify语句中保留默认值约束,否则就删除了 +alter table 表名称 modify 字段名 数据类型 default 默认值 not null; +4、如何删除默认值约束(了解) +alter table 表名称 modify 字段名 数据类型 ;#删除默认值约束,也不保留非空约束 + +alter table 表名称 modify 字段名 数据类型 not null; #删除默认值约束,保留非空约束 +14.7 自增属性 +1、作用 +作用:给某个字段自动赋值,这个值是一直往上增加,如果没有特意干扰的,每次自增1. +2、关键字:auto_increment +3、特点和要求 +(1)一个表只能有一个自增字段,因为一个表只有一个AUTO_INCREMENT属性记录自增字段值 +(2)并且自增字段只能是key字段,即定义了主键、唯一键等键约束的字段。 +一般都是给主键和唯一键加自增。 +(3)自增字段应该是数值类型,一般都是整数类型。 +(4)AUTO_INCREMENT属性值 必须 > 当前自增字段的最大值 +(5)如果自增列指定了 0 和 null,会在当前最大值的基础上自增, +如果自增列手动指定了具体值,直接赋值为具体值。 +14.8 检查约束 +1、作用 +检查(CHECK) 约束用于限制字段中的值的范围。如果对单个字段定义 CHECK 约束,那么该字段只允许特定范围的值。如果对一个表定义 CHECK 约束,那么此约束会基于行中其他字段的值在特定的字段中对值进行限制。 +在MySQL 8.0.16版本之前, CREATE TABLE语句支持给单个字段定义CHECK约束的语法,但是不起作用。 +2、关键字:check +例如MySQL8.0之前,就算给表定义了检查约束,也不起作用。在MySQL8.0.16版本之后,CREATE TABLE语句既支持给单个字段定义列级CHECK约束的语法,还支持定义表级CHECK约束的语法。 +3、如何定义检查约束 +(1)建表时 +#在建表时,可以指定检查约束 +create table 表名称( + 字段名1 数据类型 check(条件), #在字段后面直接加检查约束 + 字段名2 数据类型, + 字段名3 数据类型, + check (条件) #可以限定两个字段之间的取值条件 +); + +#在建表时,可以指定检查约束 +create table 表名称( + 字段名1 数据类型 check(条件) enforced, #在字段后面直接加检查约束 + 字段名2 数据类型, + 字段名3 数据类型, + check (条件) enforced #可以限定两个字段之间的取值条件 +); +14.9 外键约束(了解) +外键约束会影响性能,效率,所以很多人不愿意加外键约束。 +学生问题: +(1)如果两个表之间有关系(一对一、一对多),比如:员工表和部门表(一对多),它们之间是否一定要建外键约束? +答:不是的 +(2)建和不建外键约束有什么区别? +答: +建外键约束,你的操作(创建表、删除表、添加、修改、删除)会受到限制,从语法层面受到限制。例如:在员工表中不可能添加一个员工信息,它的部门的值在部门表中找不到。 +不建外键约束,你的操作(创建表、删除表、添加、修改、删除)不受限制,要保证数据的引用完整性,只能依靠程序员的自觉,或者是在Java程序中进行限定。例如:在员工表中,可以添加一个员工的信息,它的部门指定为一个完全不存在的部门。 +(3)那么建和不建外键约束和查询有没有关系? +答:没有 +1、作用 +限定某个表的某个字段的引用完整性, +比如:员工表的员工所在部门的选择,必须在部门表能找到对应的部分。 +2、关键字:foreign key +3、主表和从表/父表和子表 +主表(父表):被引用的表,被参考的表 +从表(子表):引用别人的表,参考别人的表 +例如:员工表的员工所在部门这个字段的值要参考部门表, + 部门表是主表,员工表是从表。 +例如:学生表、课程表、选课表 + 选课表的学生和课程要分别参考学生表和课程表, + 学生表和课程表是主表,选课表是从表。 +4、特点 +(1)在“从表”中指定外键约束,并且一个表可以建立多个外键约束 +(2)创建(create)表时就指定外键约束的话,先创建主表,再创建从表 +(3)删表时,先删从表(或先删除外键约束),再删除主表 +(4)从表的外键列,必须引用/参考主表的键列(主键或唯一键) +为什么?因为被依赖/被参考的值必须是唯一的 +(5)从表的外键列的数据类型,要与主表被参考/被引用的列的数据类型一致,并且逻辑意义一致。 +例如:都是表示部门编号,都是int类型。 +(6)外键列也会自动建立索引(根据外键查询效率很高,很多) +(7)外键约束的删除,所以不会自动删除,如果要删除对应的索引,必须手动删除 +5、如何指定外键约束 +(1)建表时 +create table 主表名称( + 字段1 数据类型 primary key, + 字段2 数据类型 +); + +create table 从表名称( + 字段1 数据类型 primary key, + 字段2 数据类型, + foreign key (从表的某个字段) references 主表名(被参考字段) +); +#(从表的某个字段)的数据类型必须与主表名(被参考字段)的数据类型一致,逻辑意义也一样 +#(从表的某个字段)的字段名可以与主表名(被参考字段)的字段名一样,也可以不一样 +#演示外键约束 +/* +1、作用: +用来限定子表和父表的引用关系。 +子表的外键字段值必须在父类被引用字段值的范围内。 + +2、外键约束一定是有两个表的角色。 +其中一个作为子表(又称为从表),另一个作为父表(又称为主表)。 + +子表外键字段的值要从父表被引用字段的值中选择。 + +例如:员工表中记录员工信息,其中有一个字段是“部门编号”,表示这个员工所属的部门。 + 部门的信息是记录在部门表中, + 但是员工表的“部门编号”字段的值不能随意填写,需要参考/引用“部门表”的部门记录。 + + 员工表是子表,引用别人,受部门表的牵制/范围管辖。 + 部门表示父表,被别人引用。 + +例如:商品表、用户表、订单表、订单明细表 + 商品表里面记录了商品信息(商品名称、价格、库存量...) + 用户表里面记录了用户信息(用户名、密码、账户余额...) + 订单表里面记录了订单信息(订单编号、订单总价格、订单商品总数量、收获地址...) + 订单明细表记录了订单中每一个明细(商品编号、订单编号、价格、数量....) + + 中午下了一个订单,买了“米粉”、“袜子”、“手机贴膜”、“高压锅” + 订单编号:112122123222222 + + 商品表: + 1 “米粉” 52.5 .... + 2 “袜子” 23.0 .... + 3 “手机贴膜” 15.0 .... + 4 “高压锅” 125.0 .... + + 订单明细中: + 订单编号 商品编号 数量 价格 .... + 112122123222222 1 2(盒米粉) 52.5 + 112122123222222 2 1(打) 23.0 + 112122123222222 3 1(张) 15.0 + 112122123222222 4 1(个) 125.0 + + + 订单明细表是子表,商品表和订单表是父表。 + +3、外键约束要求 +(1)外键约束必须在子表中定义 +(2)子表中要定义外键约束的字段的数据类型和逻辑意义,必须和父表中被引用字段的数据类型、逻辑意义一样。 +例如:员工表中部门编号字段 引用 部门表中的部门编号字段 + 订单明细表中的订单编号 引用 订单表中订单编号 + 订单明细表中的商品编号 引用 商品表中商品编号 + +(3)子表中要定义外键约束的字段的名字和父表中被引用字段名称可以不同。 +(4)父表中被引用的字段必须是键约束字段,一般都是主键或唯一键约束。 +此时子表和父表的关系可以是一对一或一对多的关系。 +父表是一,子表是一或多。 + +例如:父表(部门表)一条记录,对应子表(员工表)多条记录。 + 父表(订单表)一条记录,对应子表(订单明细表)一条或多条记录。 + +(5)父表必须先存在,然后才能正确建立子表的外键约束 + + +4、关键字 foreign key 和 references + + +5、外键约束约束了什么? +(1)建表的顺序,先建父表,再建子表 +(2)删表的顺序,先删子表,再删父表, +或者先删掉外键约束,然后分别删除两个表(顺序就随意了) +(3)给子表添加数据、修改外键字段的数据,受影响,因为要从父表的被引用字段范围内选值。 +(4)删除和修改父表的被引用字段的数据,受影响,因为要考虑这个值是否被子表引用了。 +(5)是否建立外键,和查询无关。 + +比喻:孩子的消费行为要受约束,在爸爸的挣钱范围内。 + 爸爸的行为也要受约束,被依赖,不是那么自由。 + 双方都会受影响。 + +``` + -- Gitee