zoukankan      html  css  js  c++  java
  • 表的基础数据类型 MySQL的mod设置 表的约束

    表的基础数据类型

    数值类型

    整数类型

    ​ 类型: tinyint, smallint, mediumint, int, bigint

    ​ 作用: 存储年龄, 等级, id, 各种号码数据等..

    ​ tinyint(m):

    ​ 小整数值: 数据类型用于保存一些范围的整数数值范围

    ​ int(m):

    ​ 大整数值: 数据类型用于保存一些范围的整数数值范围

    ​ bigint(m)

    ​ 极大整数值: 数据类型用于保存一些范围的整数数值范围

    设置无符号
    # 数据类型默认都为有符号 
    # 以int为例
    mysql> create table t(x int unsigned)
    

    ​ 注意: 对于整型来说, 数据类型后面的宽度并不是存储长度限制, 而是显示限制, 假如: int(8), name显示时不够8位则用0来填充, 够8位则正常显示.

    ​ 默认的显示宽度就是能够存储的最大的数据的长度, 比如: int无符号类型, 那么默认的显示宽度就是int(10) , 有符号就是int(11), 因为多了一个符号, 所有我们没有必要指定整数类型的数据

    浮点型

    ​ 类型: float, double

    ​ 作用: 存储薪资, 身高, 温度, 体重, 体质参数等

    ​ float(m,d):

    ​ 单精度浮点数(非准确小数值), m是整数部分 + 小数部分的总个数, d是小数点后个数. m最大值为255, d最大值为30, 例如: float(255,30)

    ​ 精确度: 随着小数的增多, 精确变得不准确

    ​ double(m,d):

    ​ 双精度浮点数(非准确小数值), m是整数部分 + 小数部分的总个数, d是小数点后个数. m最大值也为255, d最大值也为30

    ​ 精确度: 随着小数的增多, 精度比float要高, 但也会变得不准确

    ​ decimal(m,d):

    ​ 准确的小数值, m是整数部分 + 小数部分的总个数(负号不算), d是小数点后个数. m最大值为65, d最大值为30. 比float和double的整数个数少, 但是小数位数都是30位

    ​ 精确度: 随着小数的增多, 精度始终准确. 对于精确数值计算时需要用此类型, decimal能够存储精确值的原因在于其内部按照字符串存储

    ​ 精度从高到低: decimal, double, float. 前者精度高, 但是位数少. 后两者精度低, 但是整数位较多. float满足绝大多数的场景

    日期类型

    ​ 类型: date, time, datatime, imestamp, year

    ​ 作用: 存储用户注册时间, 文章发布时间, 员工入职时间, 出生时间, 过期时间等..

    ​ year:

    ​ YYYY (范围: 1901/2155)

    ​ date:

    ​ YYYY-MM-DD (范围: 1000-01-01/9999-12-31)

    ​ time:

    ​ HH:MM:DD (范围: '-838: 59: 59' / '838: 59: 59')

    ​ datetime:

    ​ YYYY-MM-DD HH: MM: SS (范围: 1000-01-01 00:00:00/9999-12-31 23: 59: 59 )

    ​ timestamp:

    ​ YYYYMMDD HHMMSS (范围: 1970-01-01 00:00:00/2037)

    ​ 在时间类型中, now()就相当于time模块中的time.time(), 并自动以格式填充

    ​ 单独插入时间时, 需要以字符串的形式, 按照对应的格式插入

    ​ 插入年份时, 尽量使用4位值

    ​ 插入两位年份时, <=69, 以20开头, >=70, 以19开头

    字符串类型

    ​ 类型: char, varchar

    ​ 作用: 名字, 信息等等

    ​ char:

    ​ 定长, 简单粗暴, 浪费空间, 存取速度快

    ​ 字符长度范围: 0~255 (一个中文是一个字符, 是utf8的三个字节)

    ​ 存储:

    ​ 指定长度为10, 存 >10个字符 则报错(严格模式下), 存<10 个字符则用空格填充直到凑够10个字符存储

    ​ 检索:

    ​ 在检索或者说查询时, 查出的结果会自动删除尾部的空格, 如果你想看到它补全空格之后的内容, 需要打开mode: pad_char_to_full_length

    ​ varchar:

    ​ 变长, 精准, 节省空间, 存取速度慢

    ​ 字符长度范围: 0~65535 (如果大于21845会提示用其他类型. mysql行最大限制为65535字节, 字符编码为utf-8)

    ​ 存储:

    ​ 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)

    ​ 检索: 尾部有空格会保存下来, 在检索或者说查询时, 也会正常显示包含空格在内的内容

    性能对比

    ​ 以char(5)和varchar(5)来比较, 加入我要存的三个人名: sb, ssb1, ssbb2

    ​ char:

    ​ 优点: 简单粗暴, 不管你是多长的数据, 只按照规定的长度来存, 5个5个的存, 三个人名就会类似这种存储: sb ssb1 ssbb2, 中间是空格补全, 取数据的时候5个5个的取, 简单粗暴速度快

    ​ 缺点: 貌似浪费空间, 并且我们将来存储的数据的长度可能会参差不齐

    ​ varchar:

    ​ varchar类型补丁唱存储数据, 更为精简和节省空间

    ​ 例如存上面三个人名的时候类似于是这样的: sbssb1ssbb2, 连着的, 如果这样存, 不知道从哪开始从哪结束, 类似于socket解决粘包, 把数据长度作为消息头.

    ​ 所以, varchar在存数据的时候, 会在每个数据前面加上一个头, 这个头是1-2个bytes的数据, 这个数据指的是后面跟着的这个数据的长度, 1bytes 能表示2**8 = 256, 两个bytes表示2**16 =65536, 能表示0-65535的数字 , 所以存储的时候是这样的: 1bytes + sb +1bytes + ssb1 + 1bytes + ssbb2, 所以存的时候会比较麻烦, 导致效率比char慢, 取的时候也慢, 先拿长度, 再取数据

    ​ 优点: 节省了一些硬盘空间, 一个acsii码的字符用一个bytes长度就能表示, 但是如果你存储的数据等于你规定的字段长度时, 反而比char占用的空间多.

    ​ 缺点: 存取速度都慢

    枚举类型与集合类型

    ​ 字段的值只能在给定范围中选择

    ​ enum 单选 只能在给定的范围内选一个值, 性别 sex 男male/女female

    ​ set 多选 在给定的范围内可以选择一个或一个以上的值

    MySQL的mode设置

    ​ 工作过程中, 一定要使用严格模式

    严格模式的设置和修改

    方式一:

    ​ 先执行select @@sql_mode, 复制查询出来的值并将其中的NO_ZERO_IN_DATE, NO_ZERO_DATE删除, 然后执行set sql_mode='修改后的值' ; 例如: set session sql_mode='STRICT_TRANS_TABLES';改为严格模式,

    session可以不用写.(此方法只在当前会话中生效, 关闭当前会话就不生效了)

    方式二:

    ​ 先执行select @@global.sql_mode, 复制查询出来的值并将其中的NO_ZERO_IN_DATE, NO_ZERO_DATE删除, 然后执行set global sql_mode = '修改后的值'(此方法在当前服务中生效, 重新mysql服务后失效)

    方法三:

    ​ 在mysql的安装目录下, 或my.cnf文件(windows系统是my.ini文件), 新增 sql_mode = STRICT_TRANS_TABLES 添加my.cnf

    表的完整性约束

    ​ 约束条件与数据类型的宽度一样, 都是可选参数

    ​ 作用: 用于保证数据的完整性和一致性

    not null 与 default

    not null

    ​ 是否可空, null表示空, 非字符串

    ​ not null -- 不可空

    ​ null -- 可空

    default

    ​ 默认值, 创建时可以指定默认值, 当插入数据时如果未主动设置, 则自动添加默认值

    注意

    ​ 当我们在插入数据时, 可以这么写insert into tb1(nid, num) values(1, 'chao'); 在插入输入的时候, 指定字段插入数据, 如果我在只给num插入值, 可以这样写insert into tb1(num) values('chao'); 还可以插入数据的时候, 指定插入数据字段的顺序: 把nid和num换个位置, 但是对应插入的值也要更换位置.

    ​ 即使你只给一个字段传值了, 那么也是生成了一整条记录, 这条记录的其他字段的值如果可以为空, 那么他们就是null空值, 如果不能为空, 就会报错(报错的是没有默认值)

    unique

    ​ 独一无二, 唯一属性: id, 身份证号等

    ​ 是一种key, 唯一键, 是在数据类型之外的附加属性, 其实还有加速查询的作用

    方法一:

    create table department(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));
    

    联合唯一

    create table service(id int primary key auto_increment, name varchar(20), name varchar(15) not null, port int not null, unique(host,port))
    

    primary key

    ​ 从约束角度看 primary key 字段的值不为空且唯一, 那我们为什不使用 not null + unique.

    ​ 主键 primary key 是 innodb 存储引擎组织数据的依据, innodb 称之为索引组织表, 一张表中必须有且只有一个主键

    ​ 一个表中可以:

    ​ 单列做主键

    ​ 多列做主键 (复合主键或者叫做联合主键)

    ​ unique key 和primary key 都是MySQL的特殊类型, 不仅仅是个字段约束条件, 还称为索引, 可以加快查询速度

    强调:

    ​ 一张表中必须有, 并且只能有一个主键字段: innodb引擎下存储表数据的时候, 会通过你的主键字段的数据来组织管理所有的数据, 将数据做成一种树形结构, 帮你较少IO次数, 提高获取定位数据, 获取数据的速度, 优化查询

    ​ 如果一张表中没有设置主键, 那么在创建表的时候, 会按照从上到下遍历你设置的字段, 直到找到not null unique的字段,自动识别成主键pri,通过desc可以看到,这样是不是不好啊,所以我们在创建表的时候,要给他一个主键,让他优化的时候用,如果没有pri也没有not null unique字段,那么innodb引擎下的mysql被逼无奈,你没有设置主键字段,主键又有不为空且唯一的约束,又不能擅自给你的字段加上这些约束,那么没办法,它只能给你添加一个隐藏字段来帮你组织数据,如果是这样,你想想,主键是不是帮我们做优化查询用的啊,这个优化是我们可以通过主键来查询数据:例如:如果我们将id设置为主键,当我们查一个id为30的数据的时候,也就是select * from tb1 where id=30;这个查询语句的速度非常快,不需要遍历前面三十条数据,就好像我们使用的字典似的,找一个字,不需要一页一页的翻书,可以首先看目录,然后看在哪一节,然后看在哪一页,一步步的范围,然后很快就找到了,这就像我们说的mysql的索引(主键、唯一键)的工作方式,一步一步的缩小范围来查找,几步就搞定了,所以通过主键你能够快速的查询到你所需要的数据,所以,如果你的主键是mysql帮你加的隐藏的字段,你查询数据的时候,就不能将这个隐藏字段作为条件来查询数据了,就不能享受到优化后的查询速度了,对么
    ​ 一张表里面,通常都应该有一个id字段,而且通常把这个id字段作为主键,当然你非要让其他的字段作为主键也是可以的,看你自己的设计,创建表的时候,一般都会写create table t1(id int primary key);id int primary key这个东西在建表的时候直接就写上

    auto_increment

    ​ 约束字段为自动增长,被约束的字段必须同时被key约束,也就是说只能给约束成key的字段加自增属性,默认起始位置为1,步长也为1.

    foreign key

    ​ 外键, 建立表和表之间的关系

    一对多(多对一)

    多的表里面添加一个字段,并给这个字段加foreign key,比如:
    出版社对应书籍是多对一的关系
    1.先创建出版社表  publish表
    2.创建书籍表,外键写法:
    	create table book(
    		id int primary key,
    		name char(10),
    		pid int,
    		foreign key(pid) references publish(id)
    		);
    3.先给出版社插入数据
    

    一对一

    一对一关系
    学生表(student)和客户表(customer)
    create table student(
    		id int primary key,
    		name char(10),
    		cid int unique,
    		foreign key(cid) references customer(id)
    		);
    

    多对多

    多对多关系
    作者表和书籍表
    需要借助第三张表来完整两者的关系记录
    第三张表后创建
    create table authortobook(
    		id int primary key,
    		author_id int,
    		book_id int,
    		foreign key(author_id) references author1(id),
    		foreign key(book_id) references book(id)
    		);
    
  • 相关阅读:
    mysql 批量插入与单条插入 的效率比较
    jQuery Validate自定义验证方法实现方式
    分析比较多表查询中的IN与JOIN
    SQL中on条件与where条件的区别
    jQuery.ajax向后台传递数组问题
    jquery ajax post 传递数组 ,多checkbox 取值
    孙俪袭击入股海润影视折射啥弊端?
    [WebView学习之三]:使用WebView来创建Apps
    hdu1010 dfs+路径剪枝
    poj 3696 The Luckiest number 欧拉函数在解a^x=1modm的应用
  • 原文地址:https://www.cnblogs.com/beichen123/p/11936805.html
Copyright © 2011-2022 走看看