SQL概要与表的创建
1.表的结构
关系数据库通过类似Excel 工作表那样的、由行和列组成的二维表来管理数据。用来管理数据的二维表在关系数据库中简称为表。
根据SQL 语句的内容返回的数据同样必须是二维表的形式 ,这也是关系数据库的特征之一。返回结果如果不是二维表的SQL 语句则无法执行。
表的列(垂直方向)称为字段,它代表了保存在表中的数据项目。表的行(水平方向)称为记录,它相当于一条数据。
关系数据库必须以行为单位进行数据读写。
一个单元格中只能输入一个数据。
2.SQL 语句及其种类
SQL是为操作数据库而开发的语言。
SQL通过一条语句来描述想要进行的操作,发送给RDBMS。
SQL根据操作目的可以分为DDL、DML和DCL。
SQL 用关键字、表名、列名等组合而成的一条语句(SQL 语句)来
描述操作的内容。
2.1.DDL
DDL(Data Definition Language,数据定义语言) 用来创建或者删除存储数据用的数据库以及数据库中的表等对象。
create :创建数据库和表等对象
drop :删除数据库和表等对象
alert :修改数据库和表等对象的结构
2.2 DML
DML(Data Manipulation Language,数据操纵语言) 用来查询或者变更表中的记录。
select:查询表中的数据
insert:向表中插入新数据
updata:更新表中的数据
delete:删除表中的数据
2.3DCL
DCL(Data Control Language,数据控制语言) 用来确认或者取消对数据库中的数据进行的变更。除此之外,还可以对RDBMS 的用户是否有权限操作数据库中的对象(数据库表等)进行设定。
commit: 确认对数据库中的数据进行的变更
rollback: 取消对数据库中的数据进行的变更
grant: 赋予用户操作权限
revoke: 取消用户的操作权限
3.表的创建
3.1创建数据库
create database <数据库名称>;
例:create database shop;
3.2创建表
create table <表名>
(<列名1> <数据类型> <该列所需约束>,
<列名2> <数据类型> <该列所需约束>,
<列名3> <数据类型> <该列所需约束>,
<列名4> <数据类型> <该列所需约束>,
.. .
<该表的约束1>, <该表的约束2>,……)
例:
create table product
(product_id char(4) not null,
product_name varchar(100) not null,
product_type varchar(32) not null,
sale_price integer,
purchase_price interge ,
regist_date data ,
primary key (product_id));
l | ... | ... | ||
---|---|---|---|---|
4.数据类型的指定
部分数据类型
数值:tinyint、int 、bigint float、double、decimal
字符串:char、varchar、text
时间类型:data 、time、datatime、timestamp
枚举和集合类型:enum、set
4.1 tinyint型
tinyint[(m)] [unsigned] [zerofill] []表示可选
有符号:-128 ~ 127 无符号:0 ~ 255,SQL中无布尔值,使用tinyint(1)构造。
用1代表TRUE,0代表FALSE,boolean在MySQL里的类型为tinyint(1),
MySQL里有四个常量:true,false,TRUE,FALSE,它们分别代表1,0,1,0
mysql> create table t2(YON boolean);
Query OK, 0 rows affected (0.04 sec)
mysql> insert into t2(YON) values(true);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t2;
+------+
| YON |
+------+
| 1 |
+------+
mysql> create table t3(YON tinyint(1));
Query OK, 0 rows affected (0.02 sec)
mysql> insert into t3(YON) values(true);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t3;
+------+
| YON |
+------+
| 1 |
+------+
mysql> create table t4(YON tinyint(1));
Query OK, 0 rows affected (0.03 sec)
mysql> insert into t4(YON) values(0);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t4;
+------+
| YON |
+------+
| 0 |
+------+
1 row in set (0.00 sec)
4.2 int型
用来指定存储整数的列的数据类型(数字型),不能存储小数。int(5),5表示的是显示长度,其它的数据类型中都是存储宽度,所以我们来设计表的时候 int类型的字段不用加显示宽度,默认是总长度的位数+1。负数不能zerofill
mysql> create table t2(number int(1));
Query OK, 0 rows affected (0.03 sec)
mysql> insert into t2(number) values(123);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t2;
+--------+
| number |
+--------+
| 123 |
+--------+
1 row in set (0.00 sec)
4.3 float型
float[(m,d)] [unsigned] [zerofill]
M是全长,D是小数点后个数。m最大值为255,d最大值为30
mysql> create table t4(digite float(6,3) zerofill);
Query OK, 0 rows affected (0.03 sec)
mysql> insert into t4(digite) values(1.2);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t4;
+--------+
| digite |
+--------+
| 01.200 |
+--------+
4.4 char型
char 是character(字符)的缩写,是用来指定存储字符串的列的数据类型(字符型)。可以像char(10) 或者char(200) 这样,在括号中指定该列可以存储的字符串的长度(最大长度)。字符串超出最大长度的部分是无法输入到该列中的。
字符串以定长字符串的形式存储在被指定为char型的列中。所谓定长字符串,就是当列中存储的字符串长度达不到最大长度的时候,使用半角空格进行补足。例如,我们向char(8) 类型的列中输入'abc'的时候,
会以'abc'(abc 后面有5 个半角空格)的形式保存起来。
在检索或者说查询时,查出的结果会自动删除尾部的空格,除非我们打开pad_char_to_full_length SQL模式(设置SQL模式:SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';)
4.5 varchar型
同char 类型一样,varchar 型也是用来指定存储字符串的列的数据类型(字符串类型),也可以通过括号内的数字来指定字符串的长度(最大长度)。但该类型的列是以 可变长字符串 的形式来保存字符串的定长字符串在字符数未达到最大长度时会用半角空格补足,但可变长字符串不同,即使字符数未达到最大长度,也不会用半角空格补足。例如,我们向varcha(8) 类型的列中输入字符串'abc'的时候,保存的就是字符串'abc'。创建表时,定长的类型往前放,变长的往后放
mysql> create table t1(x char(5),y varchar(5));
Query OK, 0 rows affected (0.03 sec)
mysql> insert into t1 values('abc ','abc ');
Query OK, 1 row affected (0.00 sec)
mysql> select @@sql_mode;
+--------------------------------------------+
| @@sql_mode |
+--------------------------------------------+
| STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION |
+--------------------------------------------+
1 row in set (0.00 sec)
#检索时char类型的数据时,不会把末尾的空格计入字符长度(包括自己创建的)
mysql> select x,char_length(x),y,char_length(y) from t1;
+------+----------------+------+----------------+
| x | char_length(x) | y | char_length(y) |
+------+----------------+------+----------------+
| abc | 3 | abc | 4 |
+------+----------------+------+----------------+
1 row in set (0.00 sec)
mysql> SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';
Query OK, 0 rows affected (0.00 sec)
mysql> select @@sql_mode;
+-------------------------+
| @@sql_mode |
+-------------------------+
| PAD_CHAR_TO_FULL_LENGTH |
+-------------------------+
1 row in set (0.00 sec)
mysql> select x,char_length(x),y,char_length(y) from t1;
+-------+----------------+------+----------------+
| x | char_length(x) | y | char_length(y) |
+-------+----------------+------+----------------+
| abc | 5 | abc | 4 |
+-------+----------------+------+----------------+
关于:sql_mode
4.5 时间
DATE | 3 | 1000-01-01/9999-12-31 | YYYY-MM-DD | 日期值 |
---|---|---|---|---|
TIME | 3 | '-838:59:59'/'838:59:59' | HH:MM:SS | 时间值或持续时间 |
YEAR | 1 | 1901/2155 | YYYY | 年份值 |
DATETIME | 8 | 1000-01-01 00:00:00/9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值 |
TIMESTAMP | 4 | 1970-01-01 00:00:00/2038 结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07 | YYYYMMDD HHMMSS | 混合日期和时间值,时间戳 |
mysql> create table t3(y year,d date,dt datetime,t time);
Query OK, 0 rows affected (0.03 sec)
mysql> insert into t3(y,d,dt,t) values(now(),now(),now(),now());
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> select * from t3;
+------+------------+---------------------+----------+
| y | d | dt | t |
+------+------------+---------------------+----------+
| 2019 | 2019-08-21 | 2019-08-21 21:14:43 | 21:14:43 |
| 2019 | 2019-08-21 | 2019-08-21 21:14:55 | 21:14:55 |
+------+------------+---------------------+----------+
4.6 enum和set
mysql> create table t5(id int,se enum('man','woman'));
Query OK, 0 rows affected (0.03 sec)
#插入值从enum中单选
mysql> insert into t5(id,se) values(1,'man');
Query OK, 1 row affected (0.00 sec)
mysql> create table t6(id int,hobby set('sing','dance','rap'));
Query OK, 0 rows affected (0.04 sec)
#插入值从set中可多选,注意这里的语法。
mysql> insert into t6(id,hobby) values(1,'sing,rap');
Query OK, 1 row affected (0.00 sec)
mysql> select * from t6;
+------+----------+
| id | hobby |
+------+----------+
| 1 | sing,rap |
+------+----------+
5.约束的设置
约束是除了数据类型之外,对列中存储的数据进行限制或者追加条件的功能,保证数据的完整性和一致型。
另外,在创建product 表的create table语句的后面,还有下面这样的记述。primary key (product_id)这是用来给product_id 列设置主键约束的。所谓键,就是在指定特定数据时使用的列的组合。键种类多样,主键(primary key)就是可以特定一行数据的列。也就是说,如果把product_id 列指定为主键,就可以通过该列取出特定的商品数据了。反之,如果向product_id 列中输入了重复数据,就无法取出唯一的特定数据了(因为无法确定唯一的一行数据)。这样就可以为某一列设置主键约束了。
5.1 null和default
null 是代表空白(无记录)的关键字。在null 之前加上了表示否定的not,就是给该列设置了不能输入空白,也就是必须输入数据的约束(如果什么都不输入就会出错)。
default默认值,当插数据时未主动设置值时,则自动添加默认值。
mysql> create table t1(product_id int not null,pruduct_name char(10) default 'unknow');
Query OK, 0 rows affected (0.06 sec)
mysql> insert into t1(product_id) values(1);
Query OK, 1 row affected (0.01 sec)
mysql> select * from t1;
+------------+--------------+
| product_id | pruduct_name |
+------------+--------------+
| 1 | unknow |
+------------+--------------+
mysql> create table t2(id int not null default 0);
Query OK, 0 rows affected (0.03 sec)
mysql> insert into t2 values();
Query OK, 1 row affected (0.00 sec)
mysql> select * from t2;
+----+
| id |
+----+
| 0 |
+----+
5.2 unique
unique表示该列唯一,可添加多列。如果在表的最后面单独设置,例:unique(id,name)表示组合唯一,id与name有一个不同即可插入。
mysql> create table t3(id int,name char(5),unique(id,name));
Query OK, 0 rows affected (0.05 sec)
mysql> insert into t3(id,name) values(1,'a'),(2,'a');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> insert into t3(id,name) values(1,'a');
ERROR 1062 (23000): Duplicate entry '1-a' for key 'id'
5.3 primary key
在MySQL的一个表中只有唯一的一个主键,不能有多列主键,但可以有复合主键
一个表中可以:单列做主键 、多列做主键(复合主键)
约束:等价于 not null unique,字段的值不为空且唯一
存储引擎默认是(innodb):对于innodb存储引擎来说,一张表必须有一个主键。
mysql> create table t4(id int ,name char,primary key(id));
Query OK, 0 rows affected (0.03 sec)
mysql> insert into t4(id,name) values(1,'a');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t4(id,name) values(1,'b');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
mysql> insert into t4(name) values('c');
ERROR 1364 (HY000): Field 'id' doesn't have a default value
5.4 auto_increment
约束的字段为自动增长,约束的字段必须同时被key约束
mysql> create table t5(id int primary key auto_increment,name char(5));
Query OK, 0 rows affected (0.03 sec)
mysql> insert into t5(name) values('a');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t5(name) values('b');
Query OK, 1 row affected (0.00 sec)
mysql> select * from t5;
+----+------+
| id | name |
+----+------+
| 1 | a |
| 2 | b |
+----+------+
2 rows in set (0.00 sec)
mysql> delete from t5;
Query OK, 2 rows affected (0.00 sec)
#即使被删除(delete),字段仍然继续增加,如果使用truncate,则不会。
mysql> insert into t5(name) values('d');
Query OK, 1 row affected (0.00 sec)
mysql> select * from t5;
+----+------+
| id | name |
+----+------+
| 3 | d |
+----+------+
5.5外键
1.创建被关联的表
2.创建关联表
3.向被关联的表插入数据
4.向关联表插入数据
mysql> create table department(seq int primary key auto_increment,name varchar(20) not null);
Query OK, 0 rows affected (0.05 sec)
mysql> create table staff(id int primary key,name char(10),dep_seq int,constraint fk foreign key(dep_seq) references department(seq));
Query OK, 0 rows affected (0.03 sec)
mysql> insert into department(name) values('生产部'),('技术部'),('销售部'),('财务部');
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> insert into staff(id,name,dep_seq) values(1,'赵',2),(2,'钱',3);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from department;
+-----+-----------+
| seq | name |
+-----+-----------+
| 1 | 生产部 |
| 2 | 技术部 |
| 3 | 销售部 |
| 4 | 财务部 |
+-----+-----------+
4 rows in set (0.00 sec)
mysql> select * from staff;
+----+------+---------+
| id | name | dep_seq |
+----+------+---------+
| 1 | 赵 | 2 |
| 2 | 钱 | 3 |
+----+------+---------+
2 rows in set (0.00 sec)
#如果被关联的表中的某条数据被关联,则该行无法删除
#创建关联表时添加同步删除和同步更新,再去删被关联表的记录,关联表中的记录也跟着删除和更新。
create table staff(id int primary key,name char(10),dep_seq int,constraint fk foreign key(dep_seq) references department(seq) on delete cascade on update cascade);