linux12 -MYSQL数据库 -->04 数据库和数据表基础命令--01
文章目录
- 数据库的基础命令详解
- 一、数据库库相关操作
- 二、数据库表相关操作
- 三、数据库字段
- 四、数据库命令详解
- 五、表的数据类型
- 1、表和表之间的关系
- 2、表介绍
- 3、 创建表
- 4、 查看表结构
- 5、表的数据类型
- 1、数据选择有简单原则
- 2、常见的数据类型
- 1、数值类型
- 1、整数型的使用
- 2、总结
- 2、浮点型( float, double ,decimal)
- 1、浮点型及定点型的的使用
- 案例:
- 3、位类型(bit)---了解
- 1、位类型的使用
- 2、日期类型
- 1、日期类型的使用
- 2、datetime与timestamp的区别
- 区别
- 3、字符串类型(重点)
- 1、char和varchar之间的对比![在这里插入图片描述](https://img-blog.csdnimg.cn/20210702120230835.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21tOTcwOTE5,size_16,color_FFFFFF,t_70)
- 4、枚举类型与集合类型
- 5、严格模式
- 六、存储引擎
- 七、表完整性约束
- 表与表的关系
数据库的基础命令详解
一、数据库库相关操作
二、数据库表相关操作
三、数据库字段
四、数据库命令详解
1、 系统数据库
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| test |
| mysql |
| performance_schema |
==========================================================================================
# 1、四种数据库的类型
# information_schema:
虚拟库,不占用磁盘空间,存储的是数据库启动后的一些参数,如用户表信息、列信息、权限信息、字符信息等
# performance_schema:
MySQL 5.5开始新增一个数据库:主要用于收集数据库服务器性能参数,记录处理查询请求时发生的各种事件、锁等现象
# mysql:
授权库,主要存储系统用户的权限信息
# test:
MySQL数据库系统自动创建的测试数据库
2、 创建数据库
1 语法(help create database)
CREATE DATABASE 数据库名 charset utf8;
2 数据库命名规则:
可以由字母、数字、下划线、@、#、$
区分大小写
唯一性
不能使用关键字如 create select
不能单独使用数字
最长128位
3、数据库相关操作
1 查看数据库
show databases;
show create database db1;
select database();
2 选择数据库
USE 数据库名
3 删除数据库
DROP DATABASE 数据库名;
4 修改数据库
alter database db1 charset utf8;
1、数据库的相关库(database)的操作(增、删、改、查)
MySQL查看数据库(SHOW DATABASES语句)
MySQL创建数据库(CREATE DATABASE语句)
MySQL修改数据库:ALTER DATABASE用法简介
MySQL删除数据库(DROP DATABASE语句)
MySQL选择数据库(MySQL USE语句)
实例:
##############(增)##############
#格式:
create database 库名称;
create database 数据库名称 charset 编码方式;
create database 数据库名称 charset 编码方式 collate 排序规则;
#示列:
create database mm charset utf8mb4;
create database mm collate utf8mb4_unicode_ci;
create database mm
#案列:
MariaDB [(none)]> create database mm; #创建库mm
Query OK, 1 row affected (0.00 sec)
##############(删)##############
#格式:
drop database 库名称;
#示列:
drop database mm;
#案列:
MariaDB [(none)]> drop database mm; #表示删除库mm
Query OK, 0 rows affected (0.00 sec)
###############(改)##############
#格式:
alter database 库名称 charset 编码方式; #修改编码方式
#示列:
alter database mm charset gbk;
#案列:
MariaDB [(none)]> alter database mm charset gbk; #更改编码方式(一般不用)
Query OK, 1 row affected (0.00 sec)
###############(查)##############
#格式:
show databases; #查看所有库
show database 库名称; #查看指定库
#示列:
show create database mm; #查看指定的库
#案列:
MariaDB [(none)]> show create database mm; #查看mm库结构
+----------+-------------------------------------------------------------+
| Database | Create Database |
+----------+-------------------------------------------------------------+
| mm | CREATE DATABASE `mm` /*!40100 DEFAULT CHARACTER SET gbk */ |
+----------+-------------------------------------------------------------+
1 row in set (0.00 sec)
=====================================================================================
##############(选择切换库)##############
#格式:
use 数据库名称;
#示列:
use mm; #选择数据库进入
#案列:
MariaDB [(none)]> use mm; #切换库位置进入指定库
Database changed
MariaDB [mm]>
====================================================================================
#创建数据库
create database 数据库名称 charset 编码方式 collate 排序规则;
create database phpedu collate utf8mb4_unicode_ci;
#修改数据库
alter database db1 charset gbk;
#删除数据库
drop database phpedu;
#选择默认数据库
use phpedu;
#查看所以数据库
show databases;
#查看建库语句
show create database phpedu;
#查看状态
status
MariaDB [mm]> status; #查看库的详细信息
--------------
mysql Ver 15.1 Distrib 5.5.68-MariaDB, for Linux (x86_64) using readline 5.1
Connection id: 10
Current database: mm
Current user: root@localhost
......
....
#查看当前数据库
select database();
MariaDB [mm]> select database();
+------------+
| database() |
+------------+
| mm |
+------------+
1 row in set (0.00 sec)
#查看登录用户
select user();
MariaDB [mm]> select user();
+----------------+
| user() |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)
#连接数据库时就选中当前数据库myblog,直接指定进入的库
mysql -uroot -proot myblog;
2、数据库的相关表(table)的操作(增、删、改、查)
CREATE TABLE 创建表
ALTER TABLE 修改表
DROP TABLE 删除表
实例:
##############(增)##############
#格式:
create table 表名称(字段1 数据类型,字段2 数据类型…限制条件);
#示列:
create table h(id int,name varchar(16)); #创建增加表单,至少有一个字段和数据类型,最后一个字段已经最后一个数据类型结束后不加,逗号
MariaDB [(none)]> create table mm.h(id int,name varchar(16));
Query OK, 0 rows affected (0.00 sec)
##############(删)##############
#格式:
drop table 表名称;
#示列:
drop table h;
#案列
MariaDB [mm]> drop table h; #删除表h
Query OK, 0 rows affected (0.00 sec)
truncate table 表名称;
truncate table h; #清空表里面数据
#案列:
MariaDB [mm]> truncate table h; #清空表h
Query OK, 0 rows affected (0.01 sec)
##############(改)##############
#格式:
alter table 表名称(字段1 数据类型,字段2 数据类型…限制条件);
rename table 表名称 to 新名称 #改表名称
alter table 表名 charset 新编码 #改表的编码
#示列:
alter table t1 modify name varchar(20); #修改指定的字段
#案列:
MariaDB [mm]> alter table h modify name varchar(20);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
##############(查)##############
#格式:
show tables; #查看库中所有表
show create table h; #查看指定的表
desc h; #查看库中指定的表
#案列:
MariaDB [mm]> desc h;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(16) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
===========================================================================================
######(删除数据库表)
alter table table_name drop index index_name #删除表中的索引
drop table table_name #删除表
drop database database_name #删除数据库
truncate table table_name #删除表内的数据
#######(查询数据库表)
desc 表名称; #查看数据表结构
show create table 表名称; #查看建表语句
show tables; #查看库中有哪些表
3、数据库的相关表(记录)的操作(增、删、改、查)
#格式:
alter table 表名称 add 字段 字段数据类型 #添加字段
alter table 表名称 drop 字段 #删除字段
alter table 表名称 modify 字段 新的数据类型 #修改字段数据类型
alter table 表名称 change 旧字段名称 新字段 新字段数据类型 #替换字段
实例:
#################(增)#################
#格式:
insert db1.t1 values(1,"egon"),(2,"tom"),(3,"jack"); #添加表的字段数据
insert db1.t1(name,id) values("lili",4); #添加指定数据类型的的字段
insert db1.t1(id) values(5); #添加指定表的字段数据类型
#################(删)#################
#格式:
delete from 表名称 where 字段数据类型;
mysql> delete from t1 where id >2;
delete from db1.t1 where id=2; #只删除表中字段三的记录
#格式:
truncate 表名称;
truncate db1.t1; #清空表
delete from db1.t1; #清除表,一般不要这么做,直接清空表即可
#################(改)#################
#格式:
update db1.t1 set name="JACK" where id=3; #表示修改指定表下指定字段的数据类型
mysql> update t1 set name="DB" where id=2;
#################(查)#################
#格式:
select * from db1.t1; #表示查询所有的表记录
select id,name from db1.t1; #查询指定表字段数据类型
select id,name from db1.t1 where id=3; #查询指定表字段数据类型为3的
select id,name from db1.t1 where id<3; #查询指定表字段数据类型为小于3的
===========================================================
# 导入新表(数据迁移)
mysql> select id,name from t1; # t1表
+----+------+
| id | name |
+----+------+
| 1 | mm |
| 2 | egon |
+----+------+
2 rows in set (0.00 sec)
mysql> desc new_t1;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | | 0 | |
| name | varchar(22) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
mysql> select id,name from new_t1; ## new_t1表
+----+------+
| id | name |
+----+------+
| 1 | mm |
mysql> desc new_t1;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | | 0 | |
| name | varchar(22) | YES | | NULL | |
mysql> insert db2.t1(name) select name from t1; #数据迁移成功
Query OK, 2 rows affected (0.00 sec)
五、表的数据类型
1、表和表之间的关系
# 两张表
一对一 唯一对应的
多对一: 左表多个对应右表唯一对应的 #尽量不要一对一
多对多: 双向对应的 #尽量不要多对一
-- #两个--代表注释
# 进入数据库,创建表
mysql> create table t1(id int)engine=blackhole;
Query OK, 0 rows affected (0.03 sec)
mysql> create table t2(id int)engine=memory;
Query OK, 0 rows affected (0.01 sec)
mysql> create table t3(id int)engine=myisam;
Query OK, 0 rows affected (0.03 sec)
mysql> create table t4(id int)engine=innodb;
Query OK, 0 rows affected (0.04 sec)
2、表介绍
表相当于文件,表中的一条记录就相当于文件的一行内容,不同的是,表中的一条记录有对应的标题,称为表的字段
id,name,qq,age称为字段,其余的,一行内容称为一条记录
3、 创建表
#语法:
create table 表名(
字段名1 类型[(宽度) 约束条件],
字段名2 类型[(宽度) 约束条件],
字段名3 类型[(宽度) 约束条件]
);
#注意:
1. 在同一张表中,字段名是不能相同
2. 宽度和约束条件可选
3. 字段名和类型是必须的
=====================================================================================
案例:
MariaDB [db1]> insert into t1 values
-> (1,'egon',18,'male'),
-> (2,'alex',81,'female')
-> ;
MariaDB [db1]> select * from t1;
+------+------+------+--------+
| id | name | age | sex |
+------+------+------+--------+
| 1 | egon | 18 | male |
| 2 | alex | 81 | female |
+------+------+------+--------+
MariaDB [db1]> insert into t1(id) values
-> (3),
-> (4);
MariaDB [db1]> select * from t1;
+------+------+------+--------+
| id | name | age | sex |
+------+------+------+--------+
| 1 | egon | 18 | male |
| 2 | alex | 81 | female |
| 3 | NULL | NULL | NULL |
| 4 | NULL | NULL | NULL |
+------+------+------+--------+
############(案列)##########
# 创建数据库
create database mydb;
# 选择当前数据库
use mydb;
## 创建用户表结构
create table `users`(
`user_id` int(10) not null auto_increment comment '用户ID' primary key,
`user_name` varchar(20) not null comment '用户名' unique key,
`user_pwd` varchar(60) not null comment '用户密码',
`user_sex` tinyint(1) comment '0男1女' default '0',
`create_time` int(10) not null,
`update_time` timestamp not null default current_timestamp() on update current_timestamp()
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
注意注意注意:表中的最后一个字段不要加逗号
4、 查看表结构
MariaDB [db1]> describe t1; #查看表结构,可简写为desc 表名
+-------+-----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(50) | YES | | NULL | |
| sex | enum('male','female') | YES | | NULL | |
| age | int(3) | YES | | NULL | |
+-------+-----------------------+------+-----+---------+-------+
MariaDB [db1]> show create table t1\G; #查看表详细结构,可加\G
5、表的数据类型
MySQL提供了一组可以赋给表中各个列的数据类型,每个类型都强制数据满足为该数据类型预先确定的一组规则,例如大小、类型及格式。支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符类型)
1、数据选择有简单原则
#更小的通常更好:
一般情况下,应该尽量使用可以正确存储数据的最小数据类型。例如只需要存 0~200,tinyint unsigned 更好。更小的数据类型通常更快,因为它们占用更少的磁盘、内存和 CPU 缓存,并且处理时需要的 CPU 周期也更少。
#简单就好:
简单数据类型的操作通常需要更少的 CPU 周期。例如,整型比字符操作代价更低,因为字符集和校对规则(排序规则)使字符比较 比 整型比较更复杂。这里有两个例子:一个是应该使用 MySQL 内建的类型(date, time, datatime)而不是字符串来存储日期和时间,另一个是应该用无符号整型存储 IP 地址。
#尽量避免NULL:
通常情况下最好指定列为 NOT NULL,除非真的需要存储 NULL 值。如果查询中包含可为 NULL 的列,对 MySQL 来说更难优化,因为可为 NULL 的列使得索引、索引统计和值比较都更复杂。特别是计划在列上建索引,就应该尽量避免设计成可为 NULL 的列
2、常见的数据类型
1)数值类型( 整数型 、 浮点型、 位类型 )
2)日期类型(DATETIME、 TIMESTAMP、 YEAR )[常用的]
3)字符串类型(varchar 和char 、blob 和 text 类型)[常用的]
4)枚举类型与集合类型(枚举(enum)类型)
1、数值类型
1、整数型(tinyint,smallint,mediumint,int,bigint)
PS: MySQL中无布尔值,使用tinyint(1)构造
# 作用:存储年龄,等级,id,各种号码等
1、整数型的使用
========= 有符号和无符号tinyint ==========
#tinyint默认为有符号
MariaDB [db1]> create table t1(x tinyint); #默认为有符号,即数字前有正负号
MariaDB [db1]> desc t1;
MariaDB [db1]> insert into t1 values
-> (-129),
-> (-128),
-> (127),
-> (128);
MariaDB [db1]> select * from t1;
+------+
| x |
+------+
| -128 | #-129存成了-128
| -128 | #有符号,最小值为-128
| 127 | #有符号,最大值127
| 127 | #128存成了127
+------+
#设置无符号tinyint
MariaDB [db1]> create table t2(x tinyint unsigned);
MariaDB [db1]> insert into t2 values
-> (-1),
-> (0),
-> (255),
-> (256);
MariaDB [db1]> select * from t2;
+------+
| x |
+------+
| 0 | -1存成了0
| 0 | #无符号,最小值为0
| 255 | #无符号,最大值为255
| 255 | #256存成了255
+------+
============ 有符号和无符号int =============
#int默认为有符号
MariaDB [db1]> create table t3(x int); #默认为有符号整数
MariaDB [db1]> insert into t3 values
-> (-2147483649),
-> (-2147483648),
-> (2147483647),
-> (2147483648);
MariaDB [db1]> select * from t3;
+-------------+
| x |
+-------------+
| -2147483648 | #-2147483649存成了-2147483648
| -2147483648 | #有符号,最小值为-2147483648
| 2147483647 | #有符号,最大值为2147483647
| 2147483647 | #2147483648存成了2147483647
+-------------+
#设置无符号int
MariaDB [db1]> create table t4(x int unsigned);
MariaDB [db1]> insert into t4 values
-> (-1),
-> (0),
-> (4294967295),
-> (4294967296);
MariaDB [db1]> select * from t4;
+------------+
| x |
+------------+
| 0 | #-1存成了0
| 0 | #无符号,最小值为0
| 4294967295 | #无符号,最大值为4294967295
| 4294967295 | #4294967296存成了4294967295
+------------+
==============有符号和无符号bigint=============
MariaDB [db1]> create table t6(x bigint);
MariaDB [db1]> insert into t5 values
-> (-9223372036854775809),
-> (-9223372036854775808),
-> (9223372036854775807),
-> (9223372036854775808);
MariaDB [db1]> select * from t5;
+----------------------+
| x |
+----------------------+
| -9223372036854775808 |
| -9223372036854775808 |
| 9223372036854775807 |
| 9223372036854775807 |
+----------------------+
MariaDB [db1]> create table t6(x bigint unsigned);
MariaDB [db1]> insert into t6 values
-> (-1),
-> (0),
-> (18446744073709551615),
-> (18446744073709551616);
MariaDB [db1]> select * from t6;
+----------------------+
| x |
+----------------------+
| 0 |
| 0 |
| 18446744073709551615 |
| 18446744073709551615 |
+----------------------+
======用zerofill测试整数类型的显示宽度=============
MariaDB [db1]> create table t7(x int(3) zerofill);
MariaDB [db1]> insert into t7 values
-> (1),
-> (11),
-> (111),
-> (1111);
MariaDB [db1]> select * from t7;
+------+
| x |
+------+
| 001 |
| 011 |
| 111 |
| 1111 | #超过宽度限制仍然可以存
2、总结
#注: 1字节为8位,也就是8byte,二进制表示就是0 0 0 0 0 0 0 0,换算为十进制最大范围就是2的8次方减1,为255
int的存储宽度是4个Bytes,即32个bit,即2**32
无符号最大值为:4294967296-1
有符号最大值:2147483648-1
有符号和无符号的最大数字需要的显示宽度均为10,而针对有符号的最小值则需要11位才能显示完全,所以int类型默认的显示宽度为11是非常合理的
最后:整形类型,其实没有必要指定显示宽度,使用默认的就ok
一般情况下,指的是存储数据的限制 (#宽度)
create table t1(name char) #默认宽度1
# msyql5.7之后的版本,存储数据的(int 10)宽度是多少,就是的多少,多了会报错
# mysql5.7 之前的版本,就会默认到最大数(127)
2、浮点型( float, double ,decimal)
作用:存储薪资、身高、体重、体质参数等
float,double 属于浮点类型(近似值)
decimal 属于定点类型(精确值)
# 一般默认float就好了
1、浮点型及定点型的的使用
float 使用 4 个字节存储;
double 使用使用 8 个字节存储;
decimal 则是将数字打包保存到一个二进制字符串中(每 4 个字节存 9 个数字)
案例:
mysql> create table t1(x float(256,31));
ERROR 1425 (42000): Too big scale 31 specified for column 'x'. Maximum is 30.
mysql> create table t1(x float(256,30));
ERROR 1439 (42000): Display width out of range for column 'x' (max = 255)
mysql> create table t1(x float(255,30)); #建表成功
Query OK, 0 rows affected (0.02 sec)
mysql> create table t2(x double(255,30)); #建表成功
Query OK, 0 rows affected (0.02 sec)
mysql> create table t3(x decimal(66,31));
ERROR 1425 (42000): Too big scale 31 specified for column 'x'. Maximum is 30.
mysql> create table t3(x decimal(66,30));
ERROR 1426 (42000): Too-big precision 66 specified for 'x'. Maximum is 65.
mysql> create table t3(x decimal(65,30)); #建表成功
Query OK, 0 rows affected (0.02 sec)
mysql> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| t1 |
| t2 |
| t3 |
+---------------+
3 rows in set (0.00 sec)
mysql> insert into t1 values(1.1111111111111111111111111111111); #小数点后31个1
Query OK, 1 row affected (0.01 sec)
mysql> insert into t2 values(1.1111111111111111111111111111111);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t3 values(1.1111111111111111111111111111111);
Query OK, 1 row affected, 1 warning (0.01 sec)
mysql> select * from t1; #随着小数的增多,精度开始不准确
+----------------------------------+
| x |
+----------------------------------+
| 1.111111164093017600000000000000 |
+----------------------------------+
1 row in set (0.00 sec)
mysql> select * from t2; #精度比float要准确点,但随着小数的增多,同样变得不准确
+----------------------------------+
| x |
+----------------------------------+
| 1.111111111111111200000000000000 |
+----------------------------------+
1 row in set (0.00 sec)
mysql> select * from t3; #精度始终准确,d为30,于是只留了30位小数
+----------------------------------+
| x |
+----------------------------------+
| 1.111111111111111111111111111111 |
+----------------------------------+
1 row in set (0.00 sec)
3、位类型(bit)—了解
BIT(M)可以用来存放多位二进制数,M范围从1~64,如果不写默认为1位
bin()显示为二进制
hex()显示为十六进制
注意:对于位字段需要使用函数读取
1、位类型的使用
MariaDB [db1]> create table t9(id bit);
MariaDB [db1]> desc t9; #bit默认宽度为1
+-------+--------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+-------+
| id | bit(1) | YES | | NULL | |
+-------+--------+------+-----+---------+-------+
MariaDB [db1]> insert into t9 values(8);
MariaDB [db1]> select * from t9; #直接查看是无法显示二进制位的
+------+
| id |
+------+
| |
+------+
MariaDB [db1]> select bin(id),hex(id) from t9; #需要转换才能看到
+---------+---------+
| bin(id) | hex(id) |
+---------+---------+
| 1 | 1 |
+---------+---------+
MariaDB [db1]> alter table t9 modify id bit(5);
MariaDB [db1]> insert into t9 values(8);
MariaDB [db1]> select bin(id),hex(id) from t9;
+---------+---------+
| bin(id) | hex(id) |
+---------+---------+
| 1 | 1 |
| 1000 | 8 |
+---------+---------+
2、日期类型
作用:存储用户注册时间,文章发布时间,员工入职时间,出生时间,过期时间等五、存储引擎介绍
1、日期类型的使用
============year===========
MariaDB [db1]> create table t10(born_year year); #无论year指定何种宽度,最后都默认是year(4)
MariaDB [db1]> insert into t10 values
-> (1900),
-> (1901),
-> (2155),
-> (2156);
MariaDB [db1]> select * from t10;
+-----------+
| born_year |
+-----------+
| 0000 |
| 1901 |
| 2155 |
| 0000 |
+-----------+
============date,time,datetime===========
MariaDB [db1]> create table t11(d date,t time,dt datetime);
MariaDB [db1]> desc t11;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| d | date | YES | | NULL | |
| t | time | YES | | NULL | |
| dt | datetime | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
MariaDB [db1]> insert into t11 values(now(),now(),now());
MariaDB [db1]> select * from t11;
+------------+----------+---------------------+
| d | t | dt |
+------------+----------+---------------------+
| 2017-07-25 | 16:26:54 | 2017-07-25 16:26:54 |
+------------+----------+---------------------+
============timestamp===========
MariaDB [db1]> create table t12(time timestamp);
MariaDB [db1]> insert into t12 values();
MariaDB [db1]> insert into t12 values(null);
MariaDB [db1]> select * from t12;
+---------------------+
| time |
+---------------------+
| 2017-07-25 16:29:17 |
| 2017-07-25 16:30:01 |
+---------------------+
============注意啦,注意啦,注意啦===========
1. 单独插入时间时,需要以字符串的形式,按照对应的格式插入
2. 插入年份时,尽量使用4位值
3. 插入两位年份时,<=69,以20开头,比如50, 结果2050
>=70,以19开头,比如71,结果1971
MariaDB [db1]> create table t12(y year);
MariaDB [db1]> insert into t12 values
-> (50),
-> (71);
MariaDB [db1]> select * from t12;
+------+
| y |
+------+
| 2050 |
| 1971 |
+------+
===========================================================
============综合练习===========
MariaDB [db1]> create table student(
-> id int,
-> name varchar(20),
-> born_year year,
-> birth date,
-> class_time time,
-> reg_time datetime);
MariaDB [db1]> insert into student values
-> (1,'alex',"1995","1995-11-11","11:11:11","2017-11-11 11:11:11"),
-> (2,'egon',"1997","1997-12-12","12:12:12","2017-12-12 12:12:12"),
-> (3,'wsb',"1998","1998-01-01","13:13:13","2017-01-01 13:13:13");
MariaDB [db1]> select * from student;
+------+------+-----------+------------+------------+---------------------+
| id | name | born_year | birth | class_time | reg_time |
+------+------+-----------+------------+------------+---------------------+
| 1 | alex | 1995 | 1995-11-11 | 11:11:11 | 2017-11-11 11:11:11 |
| 2 | egon | 1997 | 1997-12-12 | 12:12:12 | 2017-12-12 12:12:12 |
| 3 | wsb | 1998 | 1998-01-01 | 13:13:13 | 2017-01-01 13:13:13 |
+------+------+-----------+------------+------------+---------------------+
2、datetime与timestamp的区别
在实际应用的很多场景中,MySQL的这两种日期类型都能够满足我们的需要,存储精度都为秒,但在某些情况下,会展现出他们各自的优劣。下面就来总结一下两种日期类型的区别
区别
DATETIME的日期范围是1001——9999年(时间长,读写效率要慢)
TIMESTAMP的时间范围是1970——2038年(时间短,但是效率快) #选择这个就好
# 日期类型:
create table t13(
id int,
name varchar(10),
reg_time datetime, # 注册时间
class_time time, # 上课时间
born_year date # 出生
);
insert t13 values(1,"tom","2020-11-11 11:11:11","08:30:00","1999");
======================================================================================
datetime与timestamp的区别
mysql> create table t1(x datetime not null default now()); # 需要指定传入空值时默认取当前时间
Query OK, 0 rows affected (0.01 sec)
mysql> create table t2(x timestamp); # 无需任何设置,在传空值的情况下自动传入当前时间
Query OK, 0 rows affected (0.02 sec)
mysql> insert into t1 values();
Query OK, 1 row affected (0.00 sec)
mysql> insert into t2 values();
Query OK, 1 row affected (0.00 sec)
mysql> select * from t1;
+---------------------+
| x |
+---------------------+
| 2018-07-07 01:26:14 |
+---------------------+
1 row in set (0.00 sec)
mysql> select * from t2;
+---------------------+
| x |
+---------------------+
| 2018-07-07 01:26:17 |
+---------------------+
1 row in set (0.00 sec)
# !!!注意:针对datetime或者timestamp如果是用作注册时间,那么指定not null default now()自动填充时间即可,如果是用作更新时间那么需要额外指定on update now(),该配置timestamp自带
==========================================================================================
# 案例:
mysql> create table t9(name varchar(5),x datetime not null default now());
Query OK, 0 rows affected (0.01 sec)
mysql> create table t10(name varchar(5),x datetime not null default now() on update now());
Query OK, 0 rows affected (0.01 sec)
mysql> create table t11(name varchar(5),x timestamp);
Query OK, 0 rows affected (0.02 sec)
mysql>
mysql> desc t9
-> ;
+-------+------------+------+-----+-------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+-------------------+-------+
| name | varchar(5) | YES | | NULL | |
| x | datetime | NO | | CURRENT_TIMESTAMP | |
+-------+------------+------+-----+-------------------+-------+
2 rows in set (0.01 sec)
mysql> desc t10
-> ;
+-------+------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+-------------------+-----------------------------+
| name | varchar(5) | YES | | NULL | |
| x | datetime | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+------------+------+-----+-------------------+-----------------------------+
2 rows in set (0.01 sec)
mysql> desc t11;
+-------+------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+-------------------+-----------------------------+
| name | varchar(5) | YES | | NULL | |
| x | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+------------+------+-----+-------------------+-----------------------------+
2 rows in set (0.01 sec)
mysql> mysql> into t9(name) values("egon");
Query OK, 1 row affected (0.01 sec)
mysql> insert into t10(name) values("egon");
Query OK, 1 row affected (0.00 sec)
mysql> insert into t11(name) values("egon");
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> select * from t9;
+------+---------------------+
| name | x |
+------+---------------------+
| egon | 2020-09-01 13:54:25 |
+------+---------------------+
1 row in set (0.00 sec)
mysql> select * from t10;
+------+---------------------+
| name | x |
+------+---------------------+
| egon | 2020-09-01 13:54:35 |
+------+---------------------+
1 row in set (0.00 sec)
mysql> select * from t11;
+------+---------------------+
| name | x |
+------+---------------------+
| egon | 2020-09-01 13:54:39 |
+------+---------------------+
1 row in set (0.00 sec)
mysql> update t9 set name="EGON" where name="egon";
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> update t10 set name="EGON" where name="egon";
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> update t11 set name="EGON" where name="egon";
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from t9;
+------+---------------------+
| name | x |
+------+---------------------+
| EGON | 2020-09-01 13:54:25 |
+------+---------------------+
1 row in set (0.00 sec)
mysql> select * from t10;
+------+---------------------+
| name | x |
+------+---------------------+
| EGON | 2020-09-01 13:56:22 |
+------+---------------------+
1 row in set (0.00 sec)
mysql> select * from t11;
+------+---------------------+
| name | x |
+------+---------------------+
| EGON | 2020-09-01 13:56:26 |
+------+---------------------+
1 row in set (0.00 sec)
mysql>
3、字符串类型(重点)
char和varchar括号内的参数指的都是字符的长度
#char类型:定长,简单粗暴,浪费空间,存取速度快
char的优缺点:存取速度比varchar更快,但是比varchar更占用空间
#varchar类型:变长,精准,节省空间,存取速度慢
varchar的优缺点:比char省空间。但是存取速度没有char快
1、char和varchar之间的对比
注意:char和varchar括号内的参数指的都是字符的长度
官网:https://dev.mysql.com/doc/refman/5.7/en/char.htm
# 1、char和varchar的使用
# char定长
a |ab |abc |abcd|
# varchar变长
1byte+a|1byte+ab|1byte+abc|1byte+abcd
# 第一个字节的头 放的就是(描述信息)
#char类型:定长,简单粗暴,浪费空间,存取速度快
字符长度范围:0-255(一个中文是一个字符,是utf8编码的3个字节)
存储:
存储char类型的值时,会往右填充空格来满足长度
例如:指定长度为10,存>10个字符则报错,存<10个字符则用空格填充直到凑够10个字符存储
检索:
在检索或者说查询时,查出的结果会自动删除尾部的空格,除非我们打开pad_char_to_full_length SQL模式(SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';)
# varchar类型:变长,精准,节省空间,存取速度慢
字符长度范围:0-65535(如果大于21845会提示用其他类型 。mysql行最大限制为65535字节,字符编码为utf-8:https://dev.mysql.com/doc/refman/5.7/en/column-count-limit.html)
存储:
varchar类型存储数据的真实内容,不会用空格填充,如果'ab ',尾部的空格也会被存起来
强调:varchar类型会在真实数据前加1-2Bytes的前缀,该前缀用来表示真实数据的bytes字节数(1-2Bytes最大表示65535个数字,正好符合mysql对row的最大字节限制,即已经足够使用)
如果真实的数据<255bytes则需要1Bytes的前缀(1Bytes=8bit 2**8最大表示的数字为255)
如果真实的数据>255bytes则需要2Bytes的前缀(2Bytes=16bit 2**16最大表示的数字为65535)
检索:
尾部有空格会保存下来,在检索或者说查询时,也会正常显示包含空格在内的内容
create table t15(x char(4));
create table t16(x varchar(4));
insert t15 values("abcde");
insert t16 values("abcde");
====================================================================================
# 2、charvr和char那个更省空间
按道理来charvr更省空间,实际是分情况讨论的,
字符个数小于4个,charvr更省空间,如果10000条记录,差不多9000多小于4个字符,cahrvr却更省空间
字符个数正好4个,char却更省空间,如果10000条记录,差不多9000多正好等于4个字符,cahr却更省空间
=======================================================================================
# 3、char和varchar总述
#InnoDB存储引擎:建议使用VARCHAR类型
单从数据类型的实现机制去考虑,char数据类型的处理速度更快,有时甚至可以超出varchar处理速度的50%。
但对于InnoDB数据表,内部的行存储格式没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),因此在本质上,使用固定长度的CHAR列不一定比使用可变长度VARCHAR列性能要好。因而,主要的性能因素是数据行使用的存储总量。由于CHAR平均占用的空间多于VARCHAR,因此使用VARCHAR来最小化需要处理的数据行的存储总量和磁盘I/O是比较好的。
====================================================================================
# 4、其他字符串系列(效率:char>varchar>text)
TEXT系列 TINYTEXT TEXT MEDIUMTEXT LONGTEXT
BLOB 系列 TINYBLOB BLOB MEDIUMBLOB LONGBLOB
BINARY系列 BINARY VARBINARY
text:text数据类型用于保存变长的大字符串,可以组多到65535 (2**16 − 1)个字符。
mediumtext:A TEXT column with a maximum length of 16,777,215 (2**24 − 1) characters.
longtext:A TEXT column with a maximum length of 4,294,967,295 or 4GB (2**32 − 1) characters.
# 结束一个方式: char_legth 统计字字段长度
mysql> select char_length(name) from t11;
+-------------------+
| char_length(name) |
+-------------------+
| 1 |
+-------------------+
1 row in set (0.00 sec)
mysql> select char_length(name) from t10;
+-------------------+
| char_length(name) |
+-------------------+
| 1 |
+-------------------+
"""
首先可以肯定的是 char硬盘上存的绝对是真正数据
但是mysql会自动将多余的空格删除
"""
# 扩展: 其实在实际生产种,很多看似需要用整型或者浮点型存储的数据,内部可能是用的字符类型存储
4、枚举类型与集合类型
字段的值只能在给定范围中选择,如单选框,多选框
enum (单选 )只能在给定的范围内选一个值,如:性别 sex 男male/女female
set (多选) 在给定的范围内可以选择一个或一个以上的值(爱好1,爱好2,爱好3…)
#注:
MySQL 在内部会将每个值在列表中的位置保存为整数,并且在表的 .frm 文件中保存 “数字-字符串” 映射关系的 “查找表”。
如果使用数字作为枚举常量,这种双重性很容易导致混乱
#例如:
enum('1', '2', '3') 建议尽量避免这么做。
枚举字段是按照内部存储的整数而不是定义的字符串进行排序的。
===========================================================
#枚举类型(enum)
An ENUM column can have a maximum of 65,535 distinct elements. (The practical limit is less than 3000.)
#示例:
CREATE TABLE shirts (
name VARCHAR(40),
size ENUM('x-small', 'small', 'medium', 'large', 'x-large')
);
INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'),('polo shirt','small');
#集合类型(set)
A SET column can have a maximum of 64 distinct members.
#示例:
CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));
INSERT INTO myset (col) VALUES ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');
===========================================================
MariaDB [db1]> create table consumer(
-> name varchar(50),
-> sex enum('male','female'),
-> level enum('vip1','vip2','vip3','vip4','vip5'),
#在指定范围内,多选一
-> hobby set('play','music','read','study')
#在指定范围内,多选多
-> );
MariaDB [db1]> insert into consumer values
-> ('egon','male','vip5','read,study'),
-> ('alex','female','vip1','girl');
MariaDB [db1]> select * from consumer;
+------+--------+-------+------------+
| name | sex | level | hobby |
+------+--------+-------+------------+
| egon | male | vip5 | read,study |
| alex | female | vip1 | |
+------+--------+-------+------------+
5、严格模式
mysql> show variables like '%mode%';
# 模糊匹配/查询
关键字 like
%:匹配多个字符
—:匹配任意单个字符
# 修改严格模式
set session 旨在当前窗口有效
set global 全局有效
set globql sql_mode = 'STARICT_TRANS_TABLES' #X修改完进入就生效
(5.7之后的版本自动默认设置好严格模式)
=================================================================
一般情况下,指的是存储数据的限制 (#宽度)
create table t1(name char) #默认宽度1
针对不同版本会出现不同效果
5.6版本默认没有开启严格模式,规定只能存一个字符,你给多少字符,会自动截取
5.7之后的版本开启了严格模式,规定几个字符就是,字符多了会b报错
Data too long for ..
#严格模式到底开不开呢
mysql5.7以后都是开启的;
使用数据库准则:
能尽量少让数据库干活就少干活,不要给数据库增加额外压力
+
========================================================
一般情况下,指的是存储数据的限制 (#宽度)
create table t1(name char) #默认宽度1
针对不同版本会出现不同效果
5.6版本默认没有开启严格模式,规定只能存一个字符,你给多少字符,会自动截取
5.7之后的版本开启了严格模式,规定几个字符就是,字符多了会b报错
Data too long for ..
#严格模式到底开不开呢
mysql5.7以后都是开启的;
使用数据库准则:
能尽量少让数据库干活就少干活,不要给数据库增加额外压力
六、存储引擎
1、数据架构
MySQL逻辑系统架构分为3层:
* 应用层
* MySQL服务层
* 存储引擎层
2、存储引擎三大特性
存储引擎即表类型,mysql根据不同的表类型会有不同的处理机制
# http://www.cnblogs.com/linhaifeng/articles/7213670.html
mysql架构 --> 存储引擎
存储引擎 ---- 表
视频播放 ---- mp4
文本编辑器 ---- txt
mysql> show engines; #查看搜索引擎
InnoDB存储引擎
(必须有主键,如果没有 会自上而下找一个不为空且唯一的字段为主键),如果没有为自己添加一下隐藏的字段为主键,一般id为主键 # mysql5.5版本之后默认之后的存储引擎
MEMORY存储引擎 # 内存引擎(数据全部存储在内存),断电即丢失
BLACKHOLE存储引擎 # 黑洞,无论存什么都会丢失
MyISAM存储引擎 #存储在内存,# mysql5.5版本之后默认之前的存储引擎,速度要比innodb更快,但是我们追求的是安全
InnoDB存储引擎(默认):存在硬盘上
存储引擎(读取表)就是mysql中的一个小插件,表的类型,每一种存储引擎,就有自己独特的处理表的方式,存储数据更加安全
# 三大重要特性:
Supports transactions #事务 要么全部执行成功,要么全部执行失败
row-level locking #锁机制 (行级锁)缺点,并发高 #前两个是安全的
foreign keys # 外键 (外键约束,数据和数据之间约束,防止脏数据出现)
级联删除,级联增加
# mysiam存储引擎
t1.frm:表结构
t1.MYD:数据
t1.MYI:索引
# innodb存储引擎
t2.frm:表结构
t2.ibd:表数据+索引
# mysql> create table t2(id int)engine=innodb;
# mysql> create table t2(id int)engine=myisam; 其他存储引擎类似
七、表完整性约束
约束条件/表与表之间建关系(约束)*****/修改表/赋值表](https://www.cnblogs.com/dayday-up-a/p/14359424.html)
1、default默认值
PRIMARY KEY (PK) #表示该字段为该表的(主键),可以唯一的标识记录
FOREIGN KEY (FK) #标识该字段为该表的(外键)
NOT NULL #标识该字段不能为空
UNIQUE KEY (UK) #标识该字段的值是唯一的
AUTO_INCREMENT #标识该字段的值自动增长(整数类型,而且为主键)
DEFAULT #为该字段设置默认值
UNSIGNED #无符号
ZEROFILL #使用0填充
=========================================================
1. 约束条件是否允许为空,默认NULL,可设置NOT NULL(字段不允许为空,必须赋值)
2. 字段是否有默认值,缺省的默认值是NULL,如果插入记录时不给字段赋值,此字段使用默认值
sex enum('male','female') not null default 'male'
age int unsigned NOT NULL default 20 必须为正值(无符号) 不允许为空 默认是20
3. 是否是key
主键 primary key
外键 foreign key
索引 (index,unique...)
2、not null与default(默认)
not null (不可空)
null (可空)
#不设置,默认为空,插入时,可插入空
==================not null====================
mysql> create table t1(id int); #创建t1,id字段未指定,默认可以插入空
mysql> desc t1;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
mysql> insert into t1 values(); #插入时可以插入空
#设置不为空(not null)时,插入时不能为空
mysql> create table t2(id int not null); #设置字段id不为空
mysql> desc t2;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | NO | | NULL | |
+-------+---------+------+-----+---------+-------+
mysql> insert into t2 values(); #不能插入空
ERROR 1364 (HY000): Field 'id' doesn't have a default value
#设置为default(默认)值1,插入为id为空时,默认为1,则为插入值
==================default====================
#设置id字段有默认值后,则无论id字段是null还是not null,都可以插入空,插入空默认填入default指定的默认值
mysql> create table t3(id int default 1);
mysql> alter table t3 modify id int not null default 1;
==================综合练习====================
mysql> create table student(
-> name varchar(20) not null,
-> age int(3) unsigned not null default 18,
-> sex enum('male','female') default 'male',
-> hobby set('play','study','read','music') default 'play,music'
-> );
mysql> desc student;
+-------+------------------------------------+------+-----+------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------------------------+------+-----+------------+-------+
| name | varchar(20) | NO | | NULL | |
| age | int(3) unsigned | NO | | 18 | |
| sex | enum('male','female') | YES | | male | |
| hobby | set('play','study','read','music') | YES | | play,music | |
+-------+------------------------------------+------+-----+------------+-------+
mysql> insert into student(name) values('egon');
mysql> select * from student;
+------+-----+------+------------+
| name | age | sex | hobby |
+------+-----+------+------------+
| egon | 18 | male | play,music |
+------+-----+------+------------+
3、unique(唯一约束)
# 单列唯一
============设置唯一约束 UNIQUE===============
#方法一:
create table department1(
id int,
name varchar(20) unique,
comment varchar(100)
);
#方法二:
create table department2(
id int,
name varchar(20),
comment varchar(100),
constraint uk_name unique(name)
);
#插入字段数据
mysql> insert into department1 values(1,'IT','技术');
Query OK, 1 row affected (0.00 sec)
mysql> insert into department1 values(1,'IT','技术');
ERROR 1062 (23000): Duplicate entry 'IT' for key 'name'
#not null+unique(id不为空,且唯一)
mysql> create table t1(id int not null unique);
Query OK, 0 rows affected (0.02 sec)
mysql> desc t1;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)
=============================================================
# 联合唯一
#创建
create table service(
id int primary key auto_increment,
name varchar(20),
host varchar(15) not null,
port int not null,
unique(host,port) #表示host与prot联合唯一
);
mysql> insert into service values #插入字段数据
-> (1,'nginx','192.168.0.10',80),
-> (2,'haproxy','192.168.0.20',80),
-> (3,'mysql','192.168.0.30',3306)
-> ;
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> insert into service(name,host,port) values('nginx','192.168.0.10',80); #插入失败
ERROR 1062 (23000): Duplicate entry '192.168.0.10-80' for key 'host'
4、primary key主键(提升查询速度)
1,单单从约束效果上来看primary key 等价于 not null + unique非空且唯一!!!mysql> insert into t5 values(3,'11.13.13.11',80);
ERROR 1062 (23000): Duplicate entry '11.13.13.11-80' for key 'ip'
mysql>
mysql> create table t3(id int primary key);
Query OK, 0 rows affected (0.04 sec)
mysql> insert into t3 values(1);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t3 values(2);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t3 values(null);
ERROR 1048 (23000): Column 'id' cannot be null
==========================================================================
create table t5(id int primary key);
insert t5 values(null); # 报错
insert t5 values(1),(1); #报错
insert t5 values(1),(2);
2,它除了有约束效果之外,它还是innodb存储引擎组织数据的依据
innodb存储引擎在创建表的时候必须要有primary key
因为它类似于书的目录,能够帮助提示查询效率并且也是建表的依据
# 1,一张表中有且只有一个主键,如果你没有设置主键,那么他会从上往下搜索直到遇到一个非空且唯一的字段将它自动升级为主键
create table t6(id int,name char(16),age int not all unique,addr char(32) not null unique);
# 2,如果表中没有主键也没有其他任何的非空且唯一字段,那么innodb会采用自己内部提供的一个隐藏字段作为主键,隐藏意味着你无法使用它,就无法提示查询速度
# 3,一张表中通常都应该有一个主键字段,并且通常将id/uid/sid字段作为主键(id字段)
#单个字段主键
create table t5(id int primary key,name char(16));
# 联合主键(了解)
create table t4(id int,ip char(16),port int,primary key(ip,port));
···也就意味着以后我们在创建表的时候id字段一定要加primary key
5、 auto_increment自增
# 当编号特别多的时候 人为维护太麻烦
# 创建时,不指定id,则自动增长
# 自增字段只能给主键添加,不可以给普通字段添加,否则会报错。
# delecte from 在删除表中数据的时候,主键的自增不会停止
# truncate t8 清空表数据并且重置主键
=================================================================================
create table student(
id int primary key auto_increment, #设置主键约束,自动增长
name varchar(20),
sex enum('male','female') default 'male'
);
mysql> desc student; #查看表结构
+-------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(20) | YES | | NULL | |
| sex | enum('male','female') | YES | | male | |
+-------+-----------------------+------+-----+---------+----------------+
mysql> insert into student(name) values
-> ('egon'),
-> ('alex')
-> ;
mysql> select * from student;
+----+------+------+
| id | name | sex |
+----+------+------+
| 1 | egon | male |
| 2 | alex | male |
+----+------+------+
#插入时,也可以指定id
mysql> insert into student values(4,'asb','female'); #插入时,指定id
Query OK, 1 row affected (0.00 sec)
mysql> insert into student values(7,'wsb','female');
Query OK, 1 row affected (0.00 sec)
mysql> select * from student;
+----+------+--------+
| id | name | sex |
+----+------+--------+
| 1 | egon | male |
| 2 | alex | male |
| 4 | asb | female |
| 7 | wsb | female |
+----+------+--------+
#对于自增的字段,在用delete删除后,再插入值,该字段仍按照删除前的位置继续增长(id按照之前的表结构继续增加)
mysql> delete from student; #删除所有字段
Query OK, 4 rows affected (0.00 sec)
mysql> select * from student;
Empty set (0.00 sec)
mysql> insert into student(name) values('ysb'); #插入字段
mysql> select * from student;
+----+------+------+
| id | name | sex |
+----+------+------+
| 8 | ysb | male | #字段id按照之前的增长
+----+------+------+
#对于无法清空现象,可以使用truncate清空表,delete是一条一条地删除记录,truncate是直接清空表(在删除大表,清空时用truncate)
mysql> truncate student; #truncate是直接清空表
Query OK, 0 rows affected (0.01 sec)
mysql> insert into student(name) values('egon');
Query OK, 1 row affected (0.01 sec)
mysql> select * from student;
+----+------+------+
| id | name | sex |
+----+------+------+
| 1 | egon | male | #删除后,插入字段时,重1开始增长
+----+------+------+
1 row in set (0.00 sec)
========================================================
#在创建完表后,修改自增字段的起始值
mysql> create table student(
-> id int primary key auto_increment,
-> name varchar(20),
-> sex enum('male','female') default 'male'
-> );
mysql> alter table student auto_increment=3;
mysql> show create table student;
.......
ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
mysql> insert into student(name) values('egon');
Query OK, 1 row affected (0.01 sec)
mysql> select * from student;
+----+------+------+
| id | name | sex |
+----+------+------+
| 3 | egon | male |
+----+------+------+
row in set (0.00 sec)
mysql> show create table student;
.......
ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
#也可以创建表时指定auto_increment的初始值,注意初始值的设置为表选项,应该放到括号外
create table student(
id int primary key auto_increment,
name varchar(20),
sex enum('male','female') default 'male'
)auto_increment=3;
#设置步长
sqlserver:自增步长
基于表级别
create table t1(
id int。。。
)engine=innodb,auto_increment=2 步长=2 default charset=utf8
mysql自增的步长:
show session variables like 'auto_inc%';
#基于会话级别
set session auth_increment_increment=2 #修改会话级别的步长
#基于全局级别的
set global auth_increment_increment=2 #修改全局级别的步长(所有会话都生效)
#!!!注意了注意了注意了!!!
If the value of auto_increment_offset is greater than that of auto_increment_increment, the value of auto_increment_offset is ignored.
翻译:如果auto_increment_offset的值大于auto_increment_increment的值,则auto_increment_offset的值会被忽略 ,这相当于第一步步子就迈大了,扯着了蛋
比如:设置auto_increment_offset=3,auto_increment_increment=2
mysql> set global auto_increment_increment=5;
Query OK, 0 rows affected (0.00 sec)
mysql> set global auto_increment_offset=3;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like 'auto_incre%'; #需要退出重新登录
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| auto_increment_increment | 1 |
| auto_increment_offset | 1 |
+--------------------------+-------+
create table student(
id int primary key auto_increment,
name varchar(20),
sex enum('male','female') default 'male'
);
mysql> insert into student(name) values('egon1'),('egon2'),('egon3');
mysql> select * from student;
+----+-------+------+
| id | name | sex |
+----+-------+------+
| 3 | egon1 | male |
| 8 | egon2 | male |
| 13 | egon3 | male |
+----+-------+------+
#步长:auto_increment_increment
#起始偏移量:auto_increment_offset
# 注意auto_increment通常加在key主键上 不能给普通字段加
6、外键foreign key
外键就是用来帮助我们建立表和表之间关联的
# 1、一对多表关系 关键字端建在多的一方
# 2、在创建表的时候 一定要先创建被关联表
# 3、在录入数据的时候,也必须先录入被关联表
7、结论
==============================================================================
create table t19(
id int unsigned not null default 10
);
create table t20(
id int unique
);
# primary key 主键: 能用主键字段作为查询条件就不用其它字段
# 两大用途:
# 1、约束效果:not null unique
# 2、加速查询
# 3、它还是INNODB存储引擎组织数据的依据
1、使用innodb规定一张表种必须有只有一个主键
2、没有主键的时候
# 1、从上而下查找非空且唯一的自动升级为主键
# 2、通常一般是id字段是主键
# 3、如果没有设置,那么就会内部隐藏字段为主键,无法使用到
mysql> create table t21(
->
Display all 768 possibilities? (y or n)
-> id int primary key,
->
Display all 768 possibilities? (y or n)
-> name varchar(10),
->
Display all 768 possibilities? (y or n)
-> age int
-> );
Query OK, 0 rows affected (0.04 sec)
mysql> insert t21 values
-> (1,"egon",18),
-> (2,"tom",38),
-> (3,"jack",28),
-> (4,"lili",48),
-> (5,"kkkk",58);
Query OK, 5 rows affected (0.02 sec)
Records: 5 Duplicates: 0 Warnings: 0
select * from t21 where name="tom";
select * from t21 where age=38;
select * from t21 where age>35 and age < 39;
select * from t21 where id=2;
create table t23(
id int primary key auto_increment, #自动增长
name varchar(10)
);
insert t23(name) values
('egon1'),
('egon2'),
('egon3');
============================================================================
以后在创建表的id(数据的唯一标识id,uid,sid)字段的时候
id int primary key auto_increment
# 补充
delete from 在删除表中数据的时候,主键的自增不会停止
truncate t1 清空表数据并且重置主键
innodb存储引擎 必须要有主键
# 完整性约束是保证用户对数据库所做的修改不会破坏数据的一致性,是保护数据正确性和相容性的一种手段,约束条件与数据类型的宽度是一样,都是可以选择的
二:表与表之间建关系
定义一张员工表,表中有很多字段
id name gender dep_name dep_desc
# 1 该表的组织结构不是很清晰(可忽视)
# 2 浪费硬盘空间(可忽视)
# 3 数据的扩展性极差(无法忽视)
# 如何优化?(类似于将所有的代码写在了一个py文件中)
拆分表
表与表的关系
1、一对多 (一对多,多对一,都叫一对一)
判断表与表之间关系的时候,前期不熟悉的情况下,一定要换位思考,分别站在2张表的角度考虑
员工表与部门表为例
先站在员工表,思考一个员工能否对应多个部门(一条员工数据能否对应多条部门数据) 不能!
再站在部门表,思考一个部门能否对应多个员工(一个部门数据能否对应多条员工数据) 能!
得出结论:员工表与部门表是单向的一对多,所以关系就是一对多(不能说多对一,也没有多对一)
1,一对多表关系 外键字段在多的一方
2,在创建表的时候,一定要先建被关联表
3,在录入数据的时候,也必须先录入被关联表
foregin key
# sql语句建立表关系、
create table dep(id int primary key auto_increment,dep_name char(16),dep_desc char(32));
create table emp(id int primary key auto_increment,name char(16),gender enum('male','female','others') default 'male',dep_id int, foreign key(dep_id) references dep(id));
insert dep(dep_name,dep_desc)values('sb教学部','教书育人'),('外交部','多人外交'),('nb技术部','技术能力有限部门');
insert emp(name,dep_id) values('jason',2),('egon',1),('tank',1),('kevin',3);
# 修改emp 里面的dep_id字段或者dep表里面的id字段
update dep set id=200 where id = 2; 不行
# 删除dep表里面的数据
delete from dep; 不行
===========================================================
# 1 先删除教学部对应的员工数据,之后再删除部门; 操作台频繁
# 2 真正做到数据之间有关系;更新、删除同步
级联更新、删除
create table dep(id int primary key auto_increment,dep_name char(16),dep_desc char(32));
create table emp(id int primary key auto_increment,name char(16),gender enum('male','female','others') default 'male',dep_id int, foreign key(dep_id) references dep(id)
on update cascade # 同步更新
on delete cascade # 同步删除
);
insert into dep(dep_name,dep_desc) values('教学部','教研人员'),('员工部','宿舍'), ('外交部','多人外交');
insert into emp(name,dep_id) values('mm',2),('egon',1);
mysql> update dep set dep_name=明部 where id=1; #修改
2、多对多
# 图书表和作者表
create table book(
id int primary key auto_increment,
title varchar(32),
price int,
author_id int,
foregin key(author_id) references author(id)
on update cascade
on delete cascade);
create table author(
id int primary key auto_increment,
name varchar(32),
age int,
book_id int,
foreign key(book_id) references book(id)
on update cascade
on delete cascade);
===========================================================
"""
按照上述的方式创建,一个都别想成功;
其实我们只是想记录书籍和作者的关系,
针对多对多字段表关系,不能在2张原有的表中创建外键,
需要你单独再开设一张,专门用来存储2张表数据之间的关系
# 第三张表是中间表(媒见表)
"""
create table book(
id int primary key auto_increment,
title varchar(32),
price int);
create table author(
id int primary key auto_increment,
name varchar(32),
age int);
create table book2author(
id int primary key auto_increment,
author_id int,
book_id int,
foreign key(author_id) references author(id)
on update cascade
on delete cascade,
foreign key(book_id) references book(id)
on update cascade
on delete cascade,
);
3、一对一
"""
id name age addr phone hobby email.....
如果一个表的字段特别多,每次查询又不是所有的字段都能用到,
将表一分为二(拆开)
用户表
用户表 id name age
用户详情表
id addr phonr emai...
# 站在用户表、用户详情表都不可以对应上,只是一一对应上
# 结论:
单向的一对多都不成立,只是一一对应的
一对一
# 外键字段建在任意一方都可以,但是推荐建在查询频率比较高的表中
create table authordetail(
id int primary key auto_increment,
phone int,
addr varchar(64));
create table author(
id int primary key auto_increment,
name varchar(32),
age int,
authordetail_id int unique,
foreign key(book_id) references book(id)
on update cascade
on delete cascade);
"""
4、结论
#分析步骤:
1)#先站在左表的角度去找
是否左表的多条记录可以对应右表的一条记录,如果是,则证明左表的一个字段foreign key 右表一个字段(通常是id)
2)#再站在右表的角度去找
是否右表的多条记录可以对应左表的一条记录,如果是,则证明右表的一个字段foreign key 左表一个字段(通常是id)
#foreign key的对应关系
#一对多:
如果只有步骤1成立,则是左表多对一右表
如果只有步骤2成立,则是右表多对一左表
#多对多
如果步骤1和2同时成立,则证明这两张表时一个双向的多对一,即多对多,需要定义一个这两张表的关系表来专门存放二者的关系
#一对一:
如果1和2都不成立,而是左表的一条记录唯一对应右表的一条记录,反之亦然。这种情况很简单,就是在左表foreign key右表的基础上,将左表的外键字段设置成unique即可
==========================================================
2、 foreign key(外键约束)的使用
#创建foreign key:
create table 表名(
属性名1 字段类型1 是否可以为空值(不可以需要书写not null),
属性名2 字段类型2 ...,
... ... ...,
constraint 约束名称 foreign key(属性名) references 表名(属性名)
);
#已存在的表添加foreign key
alter table 表名 add constraint 约束名称 foreign key(属性名) references 表名(属性名)
#删除外键约束
alter table 表名 drop constraint 约束名称
==========================================================
3、 建立表之间的关系
1)一对多(单项foreign key)
三张表:出版社,作者信息,书
一对多(或多对一):一个出版社可以出版多本书
关联方式:foreign key
=====================多对一或一对多=====================
create table press(
id int primary key auto_increment,
name varchar(20)
);
create table book(
id int primary key auto_increment,
name varchar(20),
press_id int not null,
foreign key(press_id) references press(id)
on delete cascade #级联更新
on update cascade #级联删除
);
insert into press(name) values
('北京工业地雷出版社'),
('人民音乐不好听出版社'),
('知识产权没有用出版社')
;
insert into book(name,press_id) values
('九阳神功',1),
('九阴真经',2),
('九阴白骨爪',2),
('独孤九剑',3),
('降龙十巴掌',2),
('葵花宝典',3)
;
2)一对一(unique+foreign key)
两张表:学生表和客户表
一对一:一个学生是一个客户,一个客户有可能变成一个学校,即一对一的关系
关联方式:foreign key+unique
#一定是student来foreign key表customer,这样就保证了:
#1 学生一定是一个客户,
#2 客户不一定是学生,但有可能成为一个学生
create table customer(
id int primary key auto_increment,
name varchar(20) not null,
qq varchar(10) not null,
phone char(16) not null
);
create table student(
id int primary key auto_increment,
class_name varchar(20) not null,
customer_id int unique, #该字段一定要是唯一的
foreign key(customer_id) references customer(id) #外键的字段一定要保证unique
on delete cascade #级联删除
on update cascade #级联更新
);
#增加客户
insert into customer(name,qq,phone) values
('李飞机','31811231',13811341220),
('王大炮','123123123',15213146809),
('守榴弹','283818181',1867141331),
('吴坦克','283818181',1851143312),
('赢火箭','888818181',1861243314),
('战地雷','112312312',18811431230)
;
#增加学生
insert into student(class_name,customer_id) values
('脱产3班',3),
('周末19期',4),
('周末19期',5)
;
==========================================================
3)多对多(建立中间表,双向的foreign key)
三张表:出版社,作者信息,书
多对多:一个作者可以写多本书,一本书也可以有多个作者,双向的一对多,即多对多
关联方式:foreign key+一张新的表
=====================多对多=====================
create table author(
id int primary key auto_increment,
name varchar(20)
);
#这张表就存放作者表与书表的关系,即查询二者的关系查这表就可以了
create table author2book(
id int not null unique auto_increment,
author_id int not null,
book_id int not null,
constraint fk_author foreign key(author_id) references author(id)
on delete cascade
on update cascade,
constraint fk_book foreign key(book_id) references book(id)
on delete cascade
on update cascade,
primary key(author_id,book_id)
);
#插入四个作者,id依次排开
insert into author(name) values('egon'),('alex'),('yuanhao'),('wpq');
#每个作者与自己的代表作如下
1 egon:
1 九阳神功
2 九阴真经
3 九阴白骨爪
4 独孤九剑
5 降龙十巴掌
6 葵花宝典
2 alex:
1 九阳神功
6 葵花宝典
3 yuanhao:
4 独孤九剑
5 降龙十巴掌
6 葵花宝典
4 wpq:
1 九阳神功
insert into author2book(author_id,book_id) values
(1,1),
(1,2),
(1,3),
(1,4),
(1,5),
(1,6),
(2,1),
(2,6),
(3,4),
(3,5),
(3,6),
(4,1)
;
八、 修改表ALTER TABLE
# mysql对大小写是不敏感的
1,修改表名
alter table 表名 rename 新表名;
mysql> alter table t20 rename new_t20;
2,增加字段
alter table 表名 add 字段名 字段类型(宽度) 约束条件;
alter table 表名 add 字段名 字段类型(宽度) 约束条件 first; # 字段在表前
alter table 表名 add 字段名 字段类型(宽度) 约束条件 after; # 字段在表尾
3,删除字段
alter table 表名 drop 字段名;
4,修改字段
alter table 表名 modify 字段名 字段类型(宽度) 约束条件;
alter table 表名 change 旧字段名 新字段名 字段类型(宽度)约束条件;
语法:
1. 修改表名
ALTER TABLE 表名
RENAME 新表名;
2. 增加字段
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…],
ADD 字段名 数据类型 [完整性约束条件…];
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…] FIRST;
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…] AFTER 字段名;
3. 删除字段
ALTER TABLE 表名
DROP 字段名;
4. 修改字段
ALTER TABLE 表名
MODIFY 字段名 数据类型 [完整性约束条件…];
# 例:
mysql> desc t20;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> alter table t20 modify name varchar(22);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
ALTER TABLE 表名
CHANGE 旧字段名 新字段名 旧数据类型 [完整性约束条件…];
# 例:
mysql> alter table t20 change name new_name varchar(20);
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
ALTER TABLE 表名
CHANGE 旧字段名 新字段名 新数据类型 [完整性约束条件…];
示例:
# 1. 修改存储引擎
mysql> alter table service
-> engine=innodb;
# 2. 添加字段
mysql> alter table student10
-> add name varchar(20) not null,
-> add age int(3) not null default 22;
mysql> alter table student10
-> add stu_num varchar(10) not null after name; //添加name字段之后
mysql> alter table student10
-> add sex enum('male','female') default 'male' first; //添加到最前面
# 3. 删除字段
mysql> alter table student10
-> drop sex;
mysql> alter table service
-> drop mac;
# 4. 修改字段类型modify
mysql> alter table student10
-> modify age int(3);
mysql> alter table student10
-> modify id int(11) not null primary key auto_increment; //修改为主键
# 5. 增加约束(针对已有的主键增加auto_increment)
mysql> alter table student10 modify id int(11) not null primary key auto_increment;
ERROR 1068 (42000): Multiple primary key defined
mysql> alter table student10 modify id int(11) not null auto_increment;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
# 6. 对已经存在的表增加复合主键
mysql> alter table service2
-> add primary key(host_ip,port);
# 7. 增加主键
mysql> alter table student1
-> modify name varchar(10) not null primary key;
# 8. 增加主键和自动增长
mysql> alter table student1
-> modify id int not null primary key auto_increment;
# 9. 删除主键
a. 删除自增约束
mysql> alter table student10 modify id int(11) not null;
b. 删除主键
mysql> alter table student10
-> drop primary key;
九、 复制表
复制表结构+记录 (key不会复制: 主键、外键和索引)
mysql> create table new_service select * from service;
只复制表结构
mysql> select * from service where 1=2; //条件为假,查不到任何记录
Empty set (0.00 sec)
mysql> create table new1_service select * from service where 1=2;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> create table t4 like employees;
十 、删除表
DROP TABLE 表名;