Mysql的建表规范与注意事项

1、库名、表名、字段名必须使用小写字母,“_”分割;库名、表名、字段名必须不超过12个字符;库名、表名、字段名见名知意,建议使用名词而不是动词。html


2、建议使用InnoDB存储引擎。mysql

存储引擎:innoDb支持事物,myisam不支持事物,建议使用innoDb, 5.5之后的默认引擘,支持事务,行级锁,更好的恢复性,高并发下性能更好,对多核,大内存,ssd等硬件支持更好。程序员

(1) MyISAM表是独立于操做系统的,这说明能够轻松地将其从Windows服务器移植到Linux服务器;每当咱们创建一个MyISAM引擎的表时,就会在本地磁盘上创建三个文件,文件名就是代表。例如,我创建了一个MyISAM引擎的tb_Demo表,那么就会生成如下三个文件:sql

1.tb_demo.frm,存储表定义;数据库

2.tb_demo.MYD,存储数据;安全

3.tb_demo.MYI,存储索引。服务器

MyISAM表没法处理事务,这就意味着有事务处理需求的表,不能使用MyISAM存储引擎。MyISAM存储引擎特别适合在如下几种状况下使用:网络

1.选择密集型的表。MyISAM存储引擎在筛选大量数据时很是迅速,这是它最突出的优势。并发

2.插入密集型的表。MyISAM的并发插入特性容许同时选择和插入数据。例如:MyISAM存储引擎很适合管理邮件或Web服务器日志数据。分布式

(2) InnoDB是一个健壮的事务型存储引擎,这种存储引擎已经被不少互联网公司使用,为用户操做很是大的数据存储提供了一个强大的解决方案。个人电脑上安装的MySQL 5.6.13版,InnoDB就是做为默认的存储引擎。InnoDB还引入了行级锁定和外键约束,在如下场合下,使用InnoDB是最理想的选择:

1.更新密集的表。InnoDB存储引擎特别适合处理多重并发的更新请求。
2.事务。InnoDB存储引擎是支持事务的标准MySQL存储引擎。
3.自动灾难恢复。与其它存储引擎不一样,InnoDB表可以自动从灾难中恢复。 4.外键约束。MySQL支持外键的存储引擎只有InnoDB。 5.支持自动增长列AUTO_INCREMENT属性。

通常来讲,若是须要事务支持,而且有较高的并发读取频率,InnoDB是不错的选择。

(3)  MEMORY   :使用MySQL Memory存储引擎的出发点是速度。

1.目标数据较小,并且被很是频繁地访问。在内存中存放数据,因此会形成内存的使用,能够经过参数max_heap_table_size控制Memory表的大小,设置此参数,就能够限制Memory表的最大大小。

2.若是数据是临时的,并且要求必须当即可用,那么就能够存放在内存表中。

3.存储在Memory表中的数据若是忽然丢失,不会对应用服务产生实质的负面影响。

(2) MERGE

MERGE存储引擎是一组MyISAM表的组合,这些MyISAM表结构必须彻底相同,尽管其使用不如其它引擎突出,可是在某些状况下很是有用。说白了,Merge表就是几个相同MyISAM表的聚合器;Merge表中并无数据,对Merge类型的表能够进行查询、更新、删除操做,这些操做其实是对内部的MyISAM表进行操做。Merge存储引擎的使用场景


3、存储精确浮点数必须使用DECIMAL替代FLOAT和DOUBLE。

(1) decimal 类型能够精确地表示很是大或很是精确的小数。大至 1028(正或负)以及有效位数多达 28 位的数字能够做为 decimal类型存储而不失其精确性。该类型对于必须避免舍入错误的应用程序(如记帐)颇有用。

一、   decimal   类型是适合财务和货币计算的   128   位数据类型。

二、   decimal不是浮点型、decimal不存在精度损失;

三、   decimal所能储存的数比double大,从double到decimal的类型转换不会出现任何问题。

四、

float 单精度浮点 32bit,

double 双精度浮点64bit,

decimal是高精度 128bit,浮点型。

float double 是 基本类型(primitive type),decimal不是。

五、  浮点数运算会有精度损失问题,有精度损失时程序不会报告,要程序员本身注意。

(2)   mysql中的数值类型(不包括整型):

IEEE754浮点数: float  (单精度) , double  或 real  (双精度)
    定点数: decimal 或 numeric
    单精度浮点数的有效数字二进制是24位,按十进制来讲,是8位;双精度浮点数的有效数字二进制是53位,按十进制来讲,是16 位

一个实数的有效数字超过8位,用单精度浮点数来表示的话,就会产生偏差!一样,若是一个实数的有效数字超过16位,用双精度浮点数来表示,也会产生偏差

(3)    IEEE754标准的计算机浮点数,在内部是用二进制表示的,但在将一个十进制数转换为二进制浮点数时,也会形成偏差,缘由是否是全部的数都能转换成有限长度的二进制数。

即一个二进制能够准确转换成十进制,但一个带小数的十进制不必定可以准确地用二进制来表示。


4、建议使用INT UNSIGNED存储IPV4。

(1) 用UNSINGED INT存储IP地址占用4字节,CHAR(15)则占用15字节。另外,计算机处理整数类型比字符串类型快。使用INT UNSIGNED而不是CHAR(15)来存储IPV4地址,经过MySQL函数inet_ntoa和inet_aton来进行转化。IPv6地址目前没有转化函数,须要使用DECIMAL或两个BIGINT来存储。

例如:

SELECT INET_ATON('209.207.224.40');

3520061480

SELECT INET_NTOA(3520061480);

209.207.224.40


5、 整形定义中不添加长度,好比使用INT,而不是INT(4)。

(1) mysql中int数据类型长度最大为11位,最少为4位,不够在前面补空格。

(2) 而mysql中int自己就是4个字节 bigint是8个字节 因此说int(X)的含义就是 int决定数据存储的字节 X表示指望数据的列宽度

在SQL语句中int表明你要建立字段的类型,int表明整型,11表明字段的长度。

整数列的显示宽度与mysql须要用多少个字符来显示该列数值,与该整数须要的存储空间的大小都没有关系,好比,无论设定了显示宽度是多少个字符,bigint都要占用8个字节。


6、短数据类型,使用TINYINT。

(1) 一样的字节数,非负存储的数值范围更大。如TINYINT有符号为 -128-127,无符号为0-255。

一、TINYINT ,字段类型,若是设置为UNSIGNED类型,只能存储从0到255的整数,不能用来储存[负数]。

二、TINYINT 型的字段若是不设置UNSIGNED类型,存储-128到127的整数。

提示:  一般,为了节省空间,应该尽量的使用最小的 [整型数据]。一个TINYINT型数据只占用一个字节,一个INT型数据占用四个字节。这看起来彷佛差异不大,可是在比较大的表中,字节数的增加是很快的。另外一方面,一旦你已经建立了一个字段,要修改它是很困难的。所以,为安全起见,你应该预测一下,一个字段所须要存储的数值最大有多是多大,而后选择适当的数据类型。

(2)

tinyint 1字节 (-128,127)

smallint 2字节 (-32768,32767)

int 无符号 0-65535

mediumint 3字节 (-8388608,8388607)

int或integer 4字节 (-2147483648,2147483647)


7、不建议使用ENUM类型,使用TINYINT来代替。

详细讲解:

提及这个ENUM, 经查阅各大技术社区的网络文摘,ENUM确实是mysql里的一个特点字段,印象里模糊记得在之前看到一些比较知名的商城系统如shopnc里面在用它,但也没细究,多是由于他能够设置字段的区间范围,会让值能够被数据库所控制,有枚举约束的功能(好比,字段只想有0和1,若是用 TINYINT(1),结果就可能出现2,那2就是赃数据了)

但ENUM也有一些比较棘手的问题,好比数据迁移的时候,他几乎不可能被其余数据库所支持,若是enum里面是字符串,对于其余数据库来讲就更郁闷了,还不能设为tinyint等类型的字段(enum虽然能够存储字符串,但对于内部来讲,仍是以顺序进行索引,好比'a','b','c',咱们也能够用索引值来获取值select * from tbl_name whre enum = 2,这与select * from tbl_name where enum = 'b'等义)若是你看明白了这两句SQL为何等义,那么你也就能够了解为何不主张用enum字段了。

也就是说,假如一个设计不合理的ENUM字段,给程序员带来的就彻底是梦魇了,好比一个enum字段的范围是('0','1','2','3','4','5'),而enum的枚举值对应的索引是从1开始的,所以,insert into table (enum)values(1),插入的并非1,而是0

另外假如你在设计好enum的枚举字段范围并使用了一段时间后,再到字段范围中加一个枚举值,而且不是加在最后,那么也就至关于把原来的范围都改变了索引值,也就是当你在查询的时候直接查询值(并加上单引号),将不会使用enum自身隐藏的索引值来获取结果了。

若是是纯数值型,仍是建议采用tinyint字段吧,毕竟它也只占一个字节,即便出现赃数据,也能够被接受,不象enum,若是纯数字型范围,更改了索引,你就不知道你查询的值是否正确了)


8、尽量不使用TEXT、BLOB类型。

  1. TEXT、BLOB类型会使查询变慢,若是须要保存超长字符集,建议用varchar(n)类型或将过大字段拆分到其余表中;

  2. 使用VARBINARY存储变长字符串,binary储存定长字符串。由于二进制字节流,不存在编码问题

    binary(n) :固定长度为 n 字节,其中 n 值从 1 到 8,000 ,存储空间为 n 字节;
    
     varbinary( n | max):可变长度,n 的取值范围为 1 至 8,000,max 是指最大存储空间是 2^31-1 个字节,即最大4GB;
    
     n:在表列定义或变量声明语句中没有指定 n,则默认长度为 1;在CAST 函数中没有指定 n,则默认长度为 30;
    
     详情:::      [http://www.cnblogs.com/ljhdo/p/4530293.html](http://www.cnblogs.com/ljhdo/p/4530293.html)

对比

一、 BLOB是一个二进制大对象,能够容纳可变数量的数据。有4种 BLOB类型:TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。它们只是可容纳值的最大长度不一样。

有4种TEXT类型:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。这些对应4种BLOB类型,有相同的最大长度和存储需求。

二、 BLOB 列被视为二进制字符串(字节字符串)。TEXT列被视为非二进制字符串(字符字符串)。BLOB列没有字符集,而且排序和比较基于列值字节的数值值。TEXT列有一个字符集,而且根据字符集的 校对规则对值进行排序和比较。

在TEXT或BLOB列的存储或检索过程当中,不存在大小写转换。

三、 在大多数方面,能够将BLOB列视为可以足够大的VARBINARY列。一样,能够将TEXT列视为VARCHAR列。BLOB和TEXT在如下几个方面不一样于VARBINARY和VARCHA

注意事项:

因为BLOB和TEXT值可能会很是长,使用它们时可能遇到一些约束:

当排序时只使用该列的前max_sort_length个字节。max_sort_length的 默认值是1024;该值能够在启动d服务器时使用--max_sort_length选项进行更改。

运行时增长max_sort_length的值能够在排序或组合时使更多的字节有意义。任何客户端能够更改其会话max_sort_length变量的值:


久、禁止在数据库中使用VARBINARY、BLOB存储图片、文件等。

若是要存储图片、文件等 采用分布式文件系统更高效


10、VARCHAR(N),N表示的是字符数不是字节数,好比VARCHAR(255),能够最大可存储255个汉字,须要根据实际的宽度来选择N。

区别:

一、char的总结:

char最大长度是255字符,注意是字符数和字符集不要紧。能够有默认值,尾部有空格会被截断。

二、varchar的总结:

varchar的最大长度65535是指能存储的字节数,其实最多只能存储65532个字节,还有3个字节用于存储长度。注意是字节数这个和字符集有关系。一个汉字字符用utf8占用3字节,用gbk占用2字节。存储的最大字符数因编码不一样而不一样一般是n=65532/3或n=65532/2个字符。能够有默认值,尾部有空格不会截断。

二 理论知识

先说明一下 MySQL 从来版本对 varchar 的定义:

4.0版本如下,varchar(50),指的是50字节,若是存放UTF8汉字时,只能存16个(每一个中文3字节)

5.0版本以上,varchar(50),指的是50字符,不管存放的是数字、字母仍是UTF8中文(每一个中文3字节),均可以存放50个

存储限制

须要额外占用字节存放字符的长度:小于255为1个字节,大于255则要2个字节

编码限制

gbk :每一个字符最多占用2个字节

utf8:每一个字符最多占用3个字节

utf8mb4 每一个字符最多占用4个字节,中文占3个字节,emoji表情符号 占用4个字节

列长度限制

MySQL定义行的长度不能超过65535,该数值限制了列的数目。好比全部列为char(128) utf8字符集,最多有65535/(128*3)=170个列。


1、表字符集选择UTF8。

(1) 使用utf8字符集,若是是汉字,占3个字节,但ASCII码字符仍是1个字节。

(2) 统一,不会有转换产生乱码风险

(3) 其余地区的用户(美国、印度、台湾)无需安装简体中文支持,就能正常看您的文字,而且不会出现乱码

(4) ISO-8859-1编码(latin1)使用了单字节内的全部空间,在支持ISO-8859-1的系统中传输和存储其余任何编码的字节流都不会被抛弃。即把其余任何编码的字节流看成ISO-8859-1编码看待都没有问题,保存的是原封不动的字节流。


12、存储年使用YEAR类型。

**    重点:: mysql的日期与时间类型:分为time、date、datetime、timestamp、year,**

(1)、类型支持:year 与 year(4),注意无year(2)的定义方式,不然报错“[Err] 1818 - Supports only YEAR or YEAR(4) column.”

create table if  not exists time(
atime  YEAR                         #year的定义,可写成year或者year(4)

) engine =innodb charset = utf8;

(2)、插入值,支持整数和字符串,支持 2位数 或者 4位数

00~69  将转换为2000~2069之间

70~99  将转换为1970~1999之间

#测试year类型insert into time values( 78);    #数据库中显示:1978
insert into time values('78'); #数据库中显示:1978

insert into time values('1978'); #数据库中显示:1978

(3)、注意点

一、 支持插入 数字0 或者 字符串0,实际显示的数值不一样

insert into time  values( 0);  #数据库中显示:0
insert into time values('0'); #数据库中显示:2000

二、year只保存年份,占用空间小

三、其余和日期有关的能够经过整型保存

时间初  : 存9位


十3、存储日期使用DATE类型。

MySQL日期类型、日期格式、存储空间、日期范围比较。

日期类型        存储空间       日期格式                 日期范围

------------ ---------   --------------------- -----------------------------------------

datetime       8 bytes   YYYY-MM-DD HH:MM:SS   1000-01-01 00:00:00 ~ 9999-12-31 23:59:59

timestamp      4 bytes   YYYY-MM-DD HH:MM:SS   1970-01-01 00:00:01 ~ 2038

date           3 bytes   YYYY-MM-DD            1000-01-01          ~ 9999-12-31

year           1 bytes   YYYY                  1901                ~ 2155


十4、存储时间(精确到秒)建议使用int/bigint类型,int使用4字节,bigint使用8个字节。

1)int (1) 4个字节存储,INT的长度是4个字节,存储空间上比datatime少,int索引存储空间也相对较小,排序和查询效率相对较高一点点 (2)可读性极差,没法直观的看到数据,可能让你很恼火

能够略微注意2038年问题的陷阱。对于MySQL而言,若是存时间戳请使用timestamp或bigint,而不要使用int。 2)TIMESTAMP

(1)4个字节储存 (2)值以UTC格式保存 (3)时区转化 ,存储时对当前的时区进行转换,检索时再转换回当前的时区。 (4)TIMESTAMP值不能早于1970或晚于2037

3)datetime (1)8个字节储存 (2)与时区无关 (3)以'YYYY-MM-DD HH:MM:SS'格式检索和显示DATETIME值。支持的范围为'1000-01-01 00:00:00'到'9999-12-31 23:59:59'a


十5、建议字段定义为NOT NULL。

**   (1)**空值是不占用空间的, not null的效率比null高

** (2) ** MySQL中的NULL实际上是占用空间的  : 打个比方来讲,你有一个杯子,空值表明杯子是真空的,NULL表明杯子中装满了空气,虽然杯子看起来都是空的,可是区别是很大的。


十6、表结构变动须要通知DBA审核。

数据库管理员 DBA :::Database Administrator

**    (1)** 每次变动不能说变就变了,否则,别人不知道,确定也是按照原来的来,报错的话,也就很差往下进行了,

每次变动,提早说,都知道,审核,DBA以为合理在审核经过,再把这些变动的,放入一个文件里,便于

查看,修改了什么。

平时数据库得维护,管理,看看这设计得是否合理,不合理的更改,

相关文章
相关标签/搜索