数据库表操作、数据类型及完整性约束
库操作补充
数据库命名规则:
- 可以由字母、数字、下划线、@、#、$
- 区分大小写
- 唯一性
- 不能使用关键字如 create select
- 不能单独使用数字
- 最长128位
表操作补充
#语法:
create table 表名(
字段名1 类型[(宽度) 约束条件],
字段名2 类型[(宽度) 约束条件],
字段名3 类型[(宽度) 约束条件]
);#注意:
1. 在同一张表中,字段名是不能相同
2. 宽度和约束条件可选、非必须,宽度指的就是字段长度约束,例如:char(10)里面的10
3. 字段名和类型是必须的
数据类型
sql_mode模式
MySQL的sql_mode合理设置:
- sql_mode是个很容易被忽视的变量,默认值是空值,在这种设置下是可以允许一些非法操作的,比如允许一些非法数据的插入。在生产环境必须将这个值设置为严格模式,所以开发、测试环境的数据库也必须要设置,这样在开发测试阶段就可以发现问题。
sql model 常用来解决下面几类问题:
- 通过设置sql mode, 可以完成不同严格程度的数据校验,有效地保障数据准备性。
- 通过设置sql model 为宽松模式,来保证大多数sql符合标准的sql语法,这样应用在不同数据库之间进行迁移时,则不需要对业务sql 进行较大的修改。
- 在不同数据库之间进行数据迁移之前,通过设置SQL Mode 可以使MySQL 上的数据更方便地迁移到目标数据库中。
sql_mode常用值如下:
ONLY_FULL_GROUP_BY:
对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,那么这个SQL是不合法的,因为列不在GROUP BY从句中
NO_AUTO_VALUE_ON_ZERO:
该值影响自增长列的插入。默认设置下,插入0或NULL代表生成下一个自增长值。如果用户 希望插入的值为0,而该列又是自增长的,那么这个选项就有用了。
STRICT_TRANS_TABLES:
在该模式下,如果一个值不能插入到一个事务表中,则中断当前的操作,对非事务表不做限制
NO_ZERO_IN_DATE:
在严格模式下,不允许日期和月份为零
NO_ZERO_DATE:
设置该值,mysql数据库不允许插入零日期,插入零日期会抛出错误而不是警告。
ERROR_FOR_DIVISION_BY_ZERO:
在INSERT或UPDATE过程中,如果数据被零除,则产生错误而非警告。如 果未给出该模式,那么数据被零除时MySQL返回NULL
NO_AUTO_CREATE_USER:
禁止GRANT创建密码为空的用户
NO_ENGINE_SUBSTITUTION:
如果需要的存储引擎被禁用或未编译,那么抛出错误。不设置此值时,用默认的存储引擎替代,并抛出一个异常
PIPES_AS_CONCAT:
将"||"视为字符串的连接操作符而非或运算符,这和Oracle数据库是一样的,也和字符串的拼接函数Concat相类似
ANSI_QUOTES:
启用ANSI_QUOTES后,不能用双引号来引用字符串,因为它被解释为识别符
ORACLE的sql_mode设置等同:PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_USER.
sql_mode模式设置和修改
方式一:(当前会话生效)先执行select @@sql_mode,复制查询出来的值并将其中的NO_ZERO_IN_DATE,NO_ZERO_DATE删除,然后执行set sql_mode = '修改后的值'或者set session sql_mode='修改后的值';
例如:set session sql_mode='STRICT_TRANS_TABLES';改为严格模式
方式二:(全局服务生效)先执行select @@global.sql_mode,复制查询出来的值并将其中的NO_ZERO_IN_DATE,NO_ZERO_DATE删除,然后执行set global sql_mode = '修改后的值'。
方法三:(永久生效)在mysql的安装目录下,配置my.ini文件(苹果系统my.cnf文件),新增 sql_mode,然后重启服务
[mysqld] sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER # 数值类型
数值类型
对于整型来说,数据类型后面的宽度并不是存储长度限制,而是显示限制,假如:int(8),那么显示时不够8位则用0来填充,够8位则正常显示,通过zerofill来测试,存储长度还是int的4个字节长度。默认的显示宽度就是能够存储的最大的数据的长度,比如:int无符号类型,那么默认的显示宽度就是int(10),有符号的就是int(11),因为多了一个符号,所以我们没有必要指定整数类型的数据,没必要指定宽度,因为默认的就能够将你存的原始数据完全显示
类型 | 大小 | 范围(有符号) | 范围(无符号) | 用途 |
---|---|---|---|---|
TINYINT | 1 字节 | (-128,127) | (0,255) | 小整数值 |
SMALLINT | 2 字节 | (-32 768,32 767) | (0,65 535) | 大整数值 |
MEDIUMINT | 3 字节 | (-8 388 608,8 388 607) | (0,16 777 215) | 大整数值 |
INT或INTEGER | 4 字节 | (-2 147 483 648,2 147 483 647) | (0,4 294 967 295) | 大整数值 |
BIGINT | 8 字节 | (-9,223,372,036,854,775,808,9 223 372 036 854 775 807) | (0,18 446 744 073 709 551 615) | 极大整数值 |
FLOAT | 4 字节 | (-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) | 0,(1.175 494 351 E-38,3.402 823 466 E+38) | 单精度 浮点数值 |
DOUBLE | 8 字节 | (-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | 双精度 浮点数值 |
DECIMAL | 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2 | 依赖于M和D的值 | 依赖于M和D的值 | 小数值 |
日期类型
类型:DATE,TIME,DATETIME ,IMESTAMP,YEAR
作用:存储用户注册时间,文章发布时间,员工入职时间,出生时间,过期时间等
YEARYYYY(范围:1901/2155)2018DATEYYYY-MM-DD(范围:1000-01-01/9999-12-31)例:2018-01-01 TIMEHH:MM:SS(范围:'-838:59:59'/'838:59:59')例:12:09:32DATETIMEYYYY-MM-DD HH:MM:SS(范围:1000-01-01 00:00:00/9999-12-31 23:59:59 Y)例: 2018-01-01 12:09:32TIMESTAMPYYYYMMDD HHMMSS(范围:1970-01-01 00:00:00/2037 年某时)
字符串类型
类型:char,varchar
作用:名字,信息等等
mysql提供的两个方法:
length(字段):查看该字段数据的字节长度
char_length(字段):查看该字段数据的字符长度
char和varchar区别:
- char和varchar最大的不同就是一个是固定长度,一个是可变长度.由于是可变长度,因此存储的是实际字符串再加上一个记录字符串长度的字节。如果分配给char或varchar列的值超过 列的最大长度,则对值进行裁剪.
- varchar(M)和char(M),M都表示字符数.varchar的最大长度为65535个字节(字符长度为utf8下21845),不同的编码所对应的最大可存储的字符数不同.char最多可以存放255个字符,不同的编码最大可用字节数不同.
类型 | 大小 | 用途 |
---|---|---|
CHAR | 0-255字节 | 定长字符串 |
VARCHAR | 0-65535 字节 | 变长字符串 |
TINYBLOB | 0-255字节 | 不超过 255 个字符的二进制字符串 |
TINYTEXT | 0-255字节 | 短文本字符串 |
BLOB | 0-65 535字节 | 二进制形式的长文本数据 |
TEXT | 0-65 535字节 | 长文本数据 |
MEDIUMBLOB | 0-16 777 215字节 | 二进制形式的中等长度文本数据 |
MEDIUMTEXT | 0-16 777 215字节 | 中等长度文本数据 |
LONGBLOB | 0-4 294 967 295字节 | 二进制形式的极大文本数据 |
LONGTEXT | 0-4 294 967 295字节 | 极大文本数据 |
枚举类型和集合类型
字段的值只能在给定范围中选择,如单选框,多选框,如果你在应用程序或者前端不做选项限制,在MySQL的字段里面也能做限制
枚举类型(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');
完整性约束
约束条件与数据类型的宽度一样,都是可选参数
作用:用于保证数据的完整性和一致性
PRIMARY KEY (PK) 标识该字段为该表的主键,可以唯一的标识记录
FOREIGN KEY (FK) 标识该字段为该表的外键
NOT NULL 标识该字段不能为空
UNIQUE KEY (UK) 标识该字段的值是唯一的
AUTO_INCREMENT 标识该字段的值自动增长(整数类型,而且为主键)
DEFAULT 为该字段设置默认值UNSIGNED 无符号
ZEROFILL 使用0填充
not null 不为空
create table t1(name char(10) not null);
注意一点:如果是非严格模式,int类型不传值的话会默认为0,因为null不是int类型的,字段是int类型,所以他会自动将null变为0
default 默认值
create table t1(name char(10) not null default 'xx');
unique 唯一,字段数据不能重复
create table t1(name char(10) unique);
primary key 主键 约束效果:不为空且唯一 not null + unique
create table t1(id int primary key);
auto_increment 自增
create table t1(id int primary key auto_increment); 前面必须是个key
foreign key
foreign key(外键其实就是标明表和表之间的关系,表和表之间如果有关系的话就三种:一对一,多对一,多对多)
1、多对一
create table Anime(id int primary key auto_increment,name char(10));
insert into Anime (name) values ('龙珠'),('火影忍者'),('秦时明月');
create table people(id int primary key auto_increment,name char(10),aid int not null,foreign key(aid) references Anime(id));
insert into people (name,aid) values ('盖聂',3),('天明',3),('鸣人',2),('悟空',1),('小樱',2);
select * from Anime;
select * from people;
2、一对一
create table skill(id int primary key auto_increment,name char(10));
insert into skill (name) values('烤山鸡'),('螺旋丸'),('龟派气功'),('怪力'),('地爆天星'),('百步飞剑');
create table people(id int primary key auto_increment,name char(10),sid int not null,foreign key(sid) references skill(id));
insert into people (name,sid) values ('盖聂',6),('天明',1),('鸣人',2),('悟空',3),('小樱',4);
select * from skill;
select * from people;
3、多对多
`mysql create table people(pid int primary key auto_increment,name char(10)); insert into people (name) values ('鸣人'),('自来也'),('木叶丸'),('阿斯玛'); create table skill(sid int primary key auto_increment,name char(10)); insert into skill (name) values ('螺旋丸'),('影分身'),('手里剑'),('灰烬烧'),('仙人模式'); create table peopletoskill(id int primary key auto_increment,pid int,sid int,foreign key(pid) references people(pid),foreign key(sid) references skill(sid)); insert into peopletoskill (pid,sid) values (1,1),(1,2),(1,3),(1,5),(2,1),(2,5),(3,1),(3,2),(3,4),(4,3),(4,4); select * from people; select * from skill; desc peopletoskill; select * from peopletoskill;