1.安装MySQL服务
2.启动与连接
启动MySQL服务
:::info net start mysqlServiceName :::
关闭MySQL服务
:::info net stop mysqlServiceName :::
启动客户端
:::info mysql -hlocalhost -uroot -p123456 ::: :::info mysql —host=localhost —user=root —password=123456 :::
连接成功页面
mysql: [Warning] Using a password on the command line interface can be insecure.Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 2Server version: 5.7.27 MySQL Community Server (GPL)Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be trademarks of their respectiveowners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql>
- 最后一行的mysql>是一个客户端的提示符,之后客户端发送给服务器的命令都需要写在这个提示符后边。
如果我们想断开客户端与服务器的连接并且关闭客户端的话,可以在mysql>提示符后输入下边任意一个命令:
1. quit1. exit1. \q
2.MySQL语句使用注意事项
命令结束符号
- 在书写完一个命令之后需要以下边这几个符号之一结尾:- ;- \g- \G
区别
- ;
mysql> SELECT NOW();+---------------------+| NOW() |+---------------------+| 2018-02-06 17:50:55 |+---------------------+1 row in set (0.00 sec)mysql>
- \g- 效果同上- \G- 它并不以表格的形式返回查询结果,而是以垂直的形式将每个列都展示在单独的一行中:- 如果查询结果的列数非常多的话,使用\G可以让我们看清结果。
mysql> SELECT NOW()\G*************************** 1. row ***************************NOW(): 2018-02-06 17:51:511 row in set (0.00 sec)mysql>
使用\c放弃本次操作
- \c 不以 ; \g \G 结尾
mysql> SELECT NOW()\cmysql>
字符串的表示
- 在命令里有时会使用到字符串,我们可以使用单引号''或者双引号""把字符串内容引起来- 这个语句只是简单的把字符串'aaa'又输出来了而已。但是一定要在字符串内容上加上引号,不然的话MySQL服务器会把它当作列名,无对应列即返回错误
mysql> SELECT 'aaa';+-----+| aaa |+-----+| aaa |+-----+1 row in set (0.00 sec)mysql> SELECT aaa;ERROR 1054 (42S22): Unknown column 'aaa' in 'field list'mysql>
3.MySQL数据类型
3.1数值类型
整数类型
- 数占用字节数的不同,MySQL把整数划分成如下所示的类型:
| 类型 | 占用的存储空间(单位:字节) | 无符号数取值范围 | 有符号数取值范围 | 含义 |
|---|---|---|---|---|
| TINYINT | 1 | 0 ~ 2⁸-1 | -2⁷ ~ 2⁷-1 | 非常小的整数 |
| SMALLINT | 2 | 0 ~ 2¹⁶-1 | -2¹⁵ ~ 2¹⁵-1 | 小的整数 |
| MEDIUMINT | 3 | 0 ~ 2²⁴-1 | -2²³ ~ 2²³-1 | 中等大小的整数 |
| INT(别名:INTEGER) | 4 | 0 ~ 2³²-1 | -2³¹ ~ 2³¹-1 | 标准的整数 |
| BIGINT | 8 | 0 ~ 2⁶⁴-1 | -2⁶³ ~ 2⁶³-1 | 大整数 |
浮点数类型
- 很显然,我们表示一个浮点数使用的字节数越多,表示尾数和指数的范围就越大,也就是说可以表示的小数范围就越大
| 类型 | 占用的存储空间(单位:字节) | 绝对值最小非0值 | 绝对值最大非0值 | 含义 |
|---|---|---|---|---|
| FLOAT | 4 | ±1.175494351E-38 | ±3.402823466E+38 | 单精度浮点数 |
| DOUBLE | 8 | ±2.2250738585072014E-308 | ±1.7976931348623157E+308 | 双精度浮点数 |
设置最大位数和小数位数
- 在定义浮点数类型时,还可以在FLOAT或者DOUBLE后边跟上两个参数
:::info
FLOAT(M, D)
DOUBLE(M, D)
:::
- M表示该小数最多需要的十进制有效数字个数。注意是有效数字个数,比方说对于小数-2.3来说有效数字个数就是2,对于小数0.9来说有效数字个数就是1。- D表示该小数的小数点后的十进制数字个数。这个好理解,小数点后有几个十进制数字,D的值就是什么。
| 类型 | 取值范围 |
|---|---|
| FLOAT(4, 1) | -999.9~999.9 |
| FLOAT(5, 1) | -9999.9~9999.9 |
| FLOAT(6, 1) | -99999.9~99999.9 |
| FLOAT(4, 0) | -9999~9999 |
| FLOAT(4, 1) | -999.9~999.9 |
| FLOAT(4, 2) | -99.99~99.99 |
- M的取值范围是1~255,D的取值范围是0~30,而且D的值必须不大于M。M和D都是可选的,如果我们省略了它们,那它们的值按照机器支持的最大值来存储。
定点数类型
- 正因为用浮点数表示小数可能会有不精确的情况,在一些情况下我们必须保证小数是精确的. 即定点数
| 类型 | 占用的存储空间(单位:字节) | 取值范围 |
|---|---|---|
| DECIMAL(M, D) | 取决于M和D | 取决于M和D |
- 此处的M和D的含义与浮点数中的含义一样。- 对于定点数类型DECIMAL(M, D)来说,M和D都是可选的,默认的M的值是10,默认的D的值是0
DECIMAL(n) = DECIMAL(n, 0)DECIMAL = DECIMAL(10) = DECIMAL(10, 0)
- M的范围是1~65,D的范围是0~30,且D的值不能超过M。
无符号数值类型
- 无符号数(就是非负数)。MySQL给我们提供了一个表示无符号数值类型的方式,就是在原数值类型后加一个单词UNSIGNED:
数值类型 UNSIGNED
- INT UNSIGNED就表示无符号整数,FLOAT UNSIGNED表示无符号浮点数,DECIMAL UNSIGNED表示无符号定点数。
3.2日期和时间类型
| 类型 | 存储空间要求 | 取值范围 | 含义 |
|---|---|---|---|
| YEAR | 1字节 | 1901~2155 | 年份值 |
| DATE | 3字节 | ‘1000-01-01’ ~ ‘9999-12-31’ | 日期值 |
| TIME | 3字节 | ‘-838:59:59’ ~ ‘838:59:59’ | 时间值 |
| DATETIME | 8字节 | ‘1000-01-01 00:00:00’ ~ ‘9999-12-31 23:59:59’ | 日期加时间值 |
| TIMESTAMP | 4字节 | ‘1970-01-01 00:00:01’ ~ ‘2038-01-19 03:14:07’ | 时间戳 |
- 在MySQL5.6.4这个版本之后,TIME、DATETIME、TIMESTAMP这几种类型添加了对毫秒、微秒的支持。由于毫秒、微秒都不到1秒,所以也被称为小数秒,MySQL最多支持6位小数秒的精度- 如果我们想让TIME、DATETIME、TIMESTAMP这几种类型支持小数秒,可以这样写:
类型(小数秒位数)其中的小数秒位数可以在0、1、2、3、4、5、6中选择
YEAR
- YEAR类型也可以写成YEAR(4),它单纯表示一个年份值,取值范围为1901 ~ 2155,仅仅占用1个字节大小而已。因为可以存储的年份值有限,如果我们想存储更大范围的年份值,可以不使用MySQL自带的YEAR类型,换成SMALLINT(2字节)或者字符串类型啥的都可以。
DATE、TIME和DATETIME
- DATE表示日期,格式是YYYY-MM-DD;- TIME表示时间,格式是hh:mm:ss[.uuuuuu]或者hhh:mm:ss[.uuuuuu](有时候要存储的小时值是三位数)- DATETIME表示日期+时间,格式是YYYY-MM-DD hh:mm:ss[.uuuuuu]。- 其中的YYYY、MM、DD、hh、mm、ss、uuuuuu分别表示年、月、日、时、分、秒、小数秒。- 需要注意的是,**DATETIME**中的时间部分表示的是一天内的时间(00:00:00 ~ 23:59:59),而 **TIME**表示的是一段时间,而且可以表示负值。
TIMESTAMP
- 我们把某个时刻距离1970-01-01 00:00:00的秒数称为时间戳。比方说当前时间是2018-01-24 11:39:21,距离1970-01-01 00:00:00的秒数为1516765161
3.3字符串类型
- 现在我们可以看一下MySQL中提供的各种字符串类型(注:其中M代表该数据类型最多能存储的字符数量,L代表我们实际向该类型的属性中存储的字符串在特定字符集下所占的字节数,W代表在该特定字符集下,编码一个字符最多需要的字节数)
| 类型 | 最大长度 | 存储空间要求 | 含义 |
|---|---|---|---|
| CHAR(M) | M个字符 | M×W个字节 | 固定长度的字符串 |
| VARCHAR(M) | M个字符 | L+1 或 L+2 个字节 | 可变长度的字符串 |
| TINYTEXT | 2⁸-1 个字节 | L+1个字节 | 非常小型的字符串 |
| TEXT | 2¹⁶-1 个字节 | L+2 个字节 | 小型的字符串 |
| MEDIUMTEXT | 2²⁴-1 个字节 | L+3个字节 | 中等大小的字符串 |
| LONGTEXT | 2³²-1 个字节 | L+4个字节 | 大型的字符串 |
CHAR(M)
- CHAR(M)中的M代表该类型最多可以存储的字符数量,注意,是字符数量,不是字节数量。其中M的取值范围是0~255。如果省略掉M的值,那它的默认值就是1,也就是说CHAR和CHAR(1)是一个意思。CHAR(0)是一种特别的类型,它只能存储空字符串''或者NULL值(我们后边会详细介绍啥是个NULL)
VARCHAR(M)
- 如果你表中的某个列需要存储字符串类型的数据,而且这些字符串长短不一,那么使用CHAR(M)可能会浪费很多存储空间,VARCHAR(M)正是为了解决这个问题而生的。
各种TEXT类型
- 虽然VARCHAR(M)已经可以存储很长的字符串了,可是有时候还是不够咋办?对于很长的字符串,设计MySQL给我们提供了TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT四种可以存储大型的字符串的类型。它们也都是变长类型,
ENUM类型和SET类型
- 它表示在给定的字符串列表里选择一个。比如我们的性别一列可以定义成 ENUM('男', '女') 类型。这个的意思就是性别一列只能在'男'或者'女'这两个字符串之间选择一个,相当于一个单选框- 有的时候某一列的值可以在给定的字符串列表中挑选多个,假设学生的基本信息加了一列兴趣属性,这个属性的值可以从给定的兴趣列表中挑选多个,那我们可以使用SET类型,它的格式如下: SET('str1', 'str2', 'str3' ⋯)- 它表示可以在给定的字符串列表里选择多个。我们的兴趣一列就可以定义成SET('打球', '画画', '扯犊子', '玩游戏')类型。这个的意思就是兴趣一列可以在给定的这几个字符串中选择一个或多个,相当于一个多选框. 效果:
| 学号 | 姓名 | ··· | 兴趣 |
|---|---|---|---|
| 20180101 | 杜子腾 | ··· | ‘打球’, ‘画画’ |
| 20180102 | 杜琦燕 | ··· | ‘扯犊子’ |
| 20180103 | 范统 | ··· | ‘扯犊子’, ‘玩游戏’ |
| 20180104 | 史珍香 | ··· | ‘画画’, ‘扯犊子’, ‘玩游戏’ |
- 综上所述,ENUM和SET类型都是一种特殊的字符串类型,在从字符串列表中单选或多选元素的时候会用得到它们。
3.4二进制类型
BIT类型
- 储单个或者多个比特位
| 类型 | 字节数 | 含义 |
|---|---|---|
| BIT(M) | 近似为(M+7)/8 | 存储M个比特位的值 |
- M的取值范围为1~64,而且M可以省略,它的默认值为1,也就是说BIT(1)和BIT的意思是一样的
BINARY(M)与VARBINARY(M)
- BINARY(M)和VARBINARY(M)对应于我们前边提到的CHAR(M)和VARCHAR(M),都是前者是固定长度的类型,后者是可变长度的类型.- 只不过BINARY(M)和VARBINARY(M)是用来存放字节的,其中的M代表该类型最多能存放的字节数量,而CHAR(M)和VARCHAR(M)是用来存储字符的,其中的M代表该类型最多能存放的字符数量。
其他的二进制类型
- TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB是针对数据量很大的二进制数据提出的,比如图片、音频、压缩文件啥的。它们很像TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT,不过各种BLOB类型是用来存储字节的,而各种TEXT类型是用来存储字符的而已。
对于比较大的二进制数据,比方说图片、音频、压缩文件什么的,通常情况下都不直接存储到数据库管理系统中,而是将它们保存到文件系统中,然后在数据库中之存放一个文件路径即可。
4.数据库的基本操作
展示数据库
- 这一版本的MySQL已经为我们内建了4个数据库,这些数据库都是给MySQL自己内部使用的,如果我们想使用MySQL存放自己的数据,首先需要创建一个属于自己的数据库。
mysql> SHOW DATABASES;+--------------------+| Database |+--------------------+| information_schema || mysql || performance_schema || sys |+--------------------+4 rows in set (0.01 sec)mysql>
创建数据库
mysql> CREATE DATABASE newDatabaseName;Query OK, 1 row affected (0.00 sec)mysql>
IF NOT EXISTS
- 我们在一个数据库已经存在的情况下再使用CREATE DATABASE去创建这个数据库会产生错误:
mysql> CREATE DATABASE newDatabaseName;ERROR 1007 (HY000): Can't create database 'newDatabaseName'; database existsmysql>
- 执行结果提示了一个ERROR,意思是数据库xiaohaizi已经存在!所以如果我们并不清楚数据库是否存在,可以使用下边的语句来创建数据库:
CREATE DATABASE IF NOT EXISTS newDatabaseName;Query OK, 1 row affected, 1 warning (0.00 sec)mysql>
- 可以看到语句执行成功了,提示的ERROR也没有了,只是结果中有1个warning,这个warning只是MySQL善意的提醒我们数据库newDatabaseName已存在而已。
warning的等级比error的等级低,如果执行某个语句后提示了warning,只是属于一个善意的提示,不影响语句的执行,而提示了error之后说明语句压根儿无法执行。
切换当前数据库
- 对于每一个连接到MySQL服务器的客户端,都有一个当前数据库的概念(也可以称之为默认数据库),我们创建的表默认都会被放到当前数据库中
USE newDatabaseName;Database changedmysql>
- 新启动客户端连接服务器时就可以指定连接建立成功后客户端的当前数据库,只要把数据库名称写在启动客户端的命令mysql -h 主机名 -u 用户名 -p密码后边就好
mysql -h localhost -u root -p123456 databaseName
删除数据库
- 删除数据库意味着里边的表就都被删除了,也就意味着你的数据都没了,所以是个极其危险的操作,使用时需要极其谨慎。
DROP DATABASE 数据库名;
IF EXISTS
- 如果某个数据库并不存在,我们仍旧调用DROP DATABASE语句去删除它,不过会报错的:
mysql> DROP DATABASE xiaohaizi;ERROR 1008 (HY000): Can't drop database 'xiaohaizi'; database doesn't existmysql>
- 避免这种报错,可以使用这种形式的语句来删除数据库:
DROP DATABASE IF EXISTS 数据库名;
5.表的基本操作
展示当前数据库中的表
SHOW TABLES;
展示其它数据库中的表
- USE语句来选择当前数据库,或者在一条语句中遇到的表分散在不同的数据库中,如果我们想在语句中使用这些表,那么就必须显式的指定这些表所属的数据库了。比如不管当前数据库是不是xiaohaizi,我们都可以调用这个语句来展示数据库xiaohaizi里边的表
mysql> SHOW TABLES FROM xiaohaizi;+---------------------+| Tables_in_xiaohaizi |+---------------------+| first_table || student_info || student_score |+---------------------+3 rows in set (0.00 sec)mysql>
创建表
基本语法
CREATE TABLE 表名 (列名1 数据类型 [列的属性],列名2 数据类型 [列的属性],...列名n 数据类型 [列的属性]);
为建表语句添加注释: COMMENT
CREATE TABLE 表名 (各个列的信息 ...) COMMENT '表的注释信息';
IF NOT EXISTS
- 和重复创建数据库一样,如果创建一个已经存在的表的话是会报错的- 加入了IF NOT EXISTS的语句表示如果指定的表名不存在则创建这个表,如果存在那就什么都不做。
CREATE TABLE IF NOT EXISTS 表名(各个列的信息 ...);
删除表
DROP TABLE 表1, 表2, ..., 表n;
IF EXISTS
- 如果我们尝试删除某个不存在的表的话会报错
mysql> DROP TABLE first_table;ERROR 1051 (42S02): Unknown table 'xiaohaizi.first_table'mysql>
- 执行结果提示了一个ERROR,提示我们要删除的表并不存在,如果想避免报错,可以使用这种删除语法.
mysql> DROP TABLE IF EXISTS first_table;Query OK, 0 rows affected, 1 warning (0.00 sec)mysql>
查看表结构
- 如下查看表结构, 效果一样- DESCRIBE 表名;- DESC 表名;- EXPLAIN 表名;- SHOW COLUMNS FROM 表名;- SHOW FIELDS FROM 表名;
mysql> DESC student_info;+-----------------+-------------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-----------------+-------------------+------+-----+---------+-------+| number | int(11) | YES | | NULL | || name | varchar(5) | YES | | NULL | || sex | enum('男','女') | YES | | NULL | || id_number | char(18) | YES | | NULL | || department | varchar(30) | YES | | NULL | || major | varchar(30) | YES | | NULL | || enrollment_time | date | YES | | NULL | |+-----------------+-------------------+------+-----+---------+-------+7 rows in set (0.00 sec)mysql>
获取创表语句
- SHOW CREATE TABLE 表名;- 使用SHOW CREATE TABLE这个语句展示出来的表结构就是我们平时创建表的语句,而且为各个列自动的添加了一些没有显式设置的默认属性
mysql> SHOW CREATE TABLE student_info;+--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Table | Create Table |+--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| student_info | CREATE TABLE `student_info` (`number` int(11) DEFAULT NULL,`name` varchar(5) DEFAULT NULL,`sex` enum('男','女') DEFAULT NULL,`id_number` char(18) DEFAULT NULL,`department` varchar(30) DEFAULT NULL,`major` varchar(30) DEFAULT NULL,`enrollment_time` date DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='学生基本信息表' |+--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+1 row in set (0.00 sec)mysql>
- 由于这行数据太长了,所以输出效果并不是很好,我们可以把原来用于标记语句结束的分号;改为\G,以垂直的方式展示每一列数据的效果可能好点:
mysql> SHOW CREATE TABLE student_info\G*************************** 1. row ***************************Table: student_infoCreate Table: CREATE TABLE `student_info` (`number` int(11) DEFAULT NULL,`name` varchar(5) DEFAULT NULL,`sex` enum('男','女') DEFAULT NULL,`id_number` char(18) DEFAULT NULL,`department` varchar(30) DEFAULT NULL,`major` varchar(30) DEFAULT NULL,`enrollment_time` date DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='学生基本信息表'1 row in set (0.00 sec)mysql>
引用其它库中的表
- 其他地方如果使用到表名的话,需要显式指定这个表所属的数据库
数据库名.表名
- 比方说我们想查看xiaohaizi数据库下first_table表的结构,但是又没有使用USE xiaohaizi语句指定当前数据库,此时可以这样写语句:
SHOW CREATE TABLE xiaohaizi.first_table\G
修改表
改表名
ALTER TABLE 旧表名 RENAME TO 新表名;
多表同时改表名
RENAME TABLE 旧表名1 TO 新表名1, 旧表名2 TO 新表名2, ... 旧表名n TO 新表名n;
改表名时移动表
- 显式声明新表名的所在库
ALTER TABLE 旧表名 RENAME TO 其它库.新表名;RENAME TABLE 旧表名1 TO 其它库.新表名1, 旧表名2 TO 新表名2, ... 旧表名n TO 新表名n;
增加列
ALTER TABLE 表名 ADD COLUMN 列名 数据类型 [列的属性];
增加列到特定位置
- 到第一列
ALTER TABLE 表名 ADD COLUMN 列名 列的类型 [列的属性] FIRST;
- 添加到指定列的后边
ALTER TABLE 表名 ADD COLUMN 列名 列的类型 [列的属性] AFTER 指定列名;
删除列
ALTER TABLE 表名 DROP COLUMN 列名;
修改列信息
ALTER TABLE 表名 MODIFY 列名 新数据类型 [新属性];
ALTER TABLE 表名 CHANGE 旧列名 新列名 新数据类型 [新属性];
6.列的属性
列的属性列表
- 每个列可以同时具有多个属性,属性声明的顺序无所谓,各个属性之间用空白隔开就好了~- 有的属性是冲突的,一个列不能具有两个冲突的属性,。如一个列不能既声明为PRIMARY KEY,又声明为UNIQUE KEY,不能既声明为DEFAULT NULL,又声明为NOT NULL。
mysql> DESC student_info;+-----------------+-------------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-----------------+-------------------+------+-----+---------+-------+| number | int(11) | NO | PRI | NULL | || name | varchar(5) | YES | | NULL | || sex | enum('男','女') | YES | | NULL | || id_number | char(18) | YES | UNI | NULL | || department | varchar(30) | YES | | NULL | || major | varchar(30) | YES | | NULL | || enrollment_time | date | YES | | NULL | |+-----------------+-------------------+------+-----+---------+-------+7 rows in set (0.00 sec)mysql>
解析:
- NULL列代表该列是否可以存储NULL,值为NO时,表示不允许存储NULL,值为YES是表示可以存储NULL。
- Key列存储关于所谓的键的信息,当值为PRI是PRIMARY KEY的缩写,代表主键;UNI是UNIQUE KEY的缩写,代表UNIQUE属性。
- Default列代表该列的默认值。
- Extra列展示一些额外的信息。比方说如果某个列具有AUTO_INCREMENT属性就会被展示在这个列里。
标识符的命名
- 避免:1. 名称中全都是数字1. 名称中有空白字符1. 名称使用了MySQL中的保留字1. 使用时: 反引号``来声明这是自定义标识符名称
简单插入语句
INSERT INTO 表名(列1, 列2, ...) VALUES(列1的值,列2的值, ...);
批量插入
INSERT INTO 表名(列1,列2, ...) VAULES(列1的值,列2的值, ...), (列1的值,列2的值, ...), (列1的值,列2的值, ...), ...;
列的默认值
- 如果我们不设置默认值,相当于指定的默认值为NULL
列名 列的类型 DEFAULT 默认值
mysql> CREATE TABLE first_table (-> first_column INT,-> second_column VARCHAR(100) DEFAULT 'abc'-> );Query OK, 0 rows affected (0.02 sec)mysql> SHOW CREATE TABLE first_table\G*************************** 1. row ***************************Table: first_tableCreate Table: CREATE TABLE `first_table` (`first_column` int(11) DEFAULT NULL,`second_column` varchar(100) DEFAULT 'abc') ENGINE=InnoDB DEFAULT CHARSET=utf81 row in set (0.00 sec)mysql>
NOT NULL属性
- 要求表中的某些列中必须有值,不能存放NULL
列名 列的类型 NOT NULL
mysql> CREATE TABLE first_table (-> first_column INT NOT NULL,-> second_column VARCHAR(100) DEFAULT 'abc'-> );Query OK, 0 rows affected (0.02 sec)mysql>
- 就不能再往这个字段里插入NULL值了.
mysql> INSERT INTO first_table(first_column, second_column) VALUES(NULL, 'aaa');ERROR 1048 (23000): Column 'first_column' cannot be nullmysql>
- 一旦对某个列定义了NOT NULL属性,那这个列的默认值就不为NULL了。上边first_column并没有指定默认值,意味着我们在使用INSERT插入行时必须显式的指定这个列的值,而不能省略它,比如这样就会报错
mysql> INSERT INTO first_table(second_column) VALUES('aaa');ERROR 1364 (HY000): Field 'first_column' doesn't have a default valuemysql>
主键
- 主键列默认是有NOT NULL属性- 一个表最多只能有一个主键,主键的值不能重复,通过主键可以找到唯一的一条记录- 如果主键只是单个列的话,可以直接在该列后声明PRIMARY KEY,比如我们把学生信息表student_info的学号列声明为主键可以这么写:
CREATE TABLE student_info (number INT PRIMARY KEY,name VARCHAR(5),sex ENUM('男', '女'),id_number CHAR(18));
- 也可以把主键的声明单独提取出来: PRIMARY KEY (列名1, 列名2, ...)- 对于多个列的组合作为主键的情况,必须使用这种单独声明的形式
CREATE TABLE student_info (number INT,name VARCHAR(5),sex ENUM('男', '女'),id_number CHAR(18),PRIMARY KEY (number));
UNIQUE属性
- 在我们向表中插入新记录的时候帮助我们校验一下某个列或者列组合的值是否重复,那么我们可以把这个列或列组合添加一个UNIQUE属性,表明该列或者列组合的值是不允许重复的。与我们在建表语句中声明主键的方式类似,为某个列声明UNIQUE属性的方式也有两种:
CREATE TABLE student_info (number INT PRIMARY KEY,name VARCHAR(5),sex ENUM('男', '女'),id_number CHAR(18) UNIQUE,);
UNIQUE [KEY] [约束名称] (列名1, 列名2, ...)
主键和UNIQUE约束的区别
- 主键和UNIQUE约束都能保证某个列或者列组合的唯一性,但是:1. 一张表中只能定义一个主键,却可以定义多个UNIQUE约束!1. 规定:主键列不允许存放NULL,而声明了UNIQUE属性的列可以存放NULL,而且NULL可以重复地出现在多条记录中!
NULL其实并不是一个值,它代表不确定,我们平常说某个列的值为NULL,意味着这一列的值尚未被填入
外键
CONSTRAINT [外键名称] FOREIGN KEY(列1, 列2, ...) REFERENCES 父表名(父列1, 父列2, ...);
CREATE TABLE student_score (number INT,subject VARCHAR(30),score TINYINT,PRIMARY KEY (number, subject),CONSTRAINT FOREIGN KEY(number) REFERENCES student_info(number));
AUTO_INCREMENT属性
- 自增。如果一个表中的某个列的数据类型是整数类型或者浮点数类型,那么这个列可以设置AUTO_INCREMENT属性。
列名 列的类型 AUTO_INCREMENT
- 非负INT类型的id列,把它设置为主键而且具有AUTO_INCREMENT属性,那我们在插入新记录时可以忽略掉这个列,或者将列值显式地指定为NULL或0,但是它的值将会递增
mysql> CREATE TABLE first_table (-> id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,-> first_column INT,-> second_column VARCHAR(100) DEFAULT 'abc'-> );Query OK, 0 rows affected (0.01 sec)
- 注意:1. 一个表中最多有一个具有AUTO_INCREMENT属性的列。1. 具有AUTO_INCREMENT属性的列必须建立索引。主键和具有UNIQUE属性的列会自动建立索引1. 拥有AUTO_INCREMENT属性的列就不能再通过指定DEFAULT属性来指定默认值。1. 一般拥有AUTO_INCREMENT属性的列都是作为主键的属性,来自动生成唯一标识一条记录的主键值。
列的注释
CREATE TABLE first_table (id int UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '自增主键',first_column INT COMMENT '第一列',second_column VARCHAR(100) DEFAULT 'abc' COMMENT '第二列') COMMENT '第一个表';
