MySQL_13_在表设计中给字段设计合适的类型

文章目录

一、前言

面试考点
1、记住所以类型,每一个类型的含义;
2、类似类型的区别;
3、开发选用原则;

本文中,重点在第二部分、第三部分、第四部分、第五部分都是重点

二、Mysql数据类型:五类(面试重点,概要)

主要包括以下五大类:

整数类型:BIT、BOOLTINY INT、SMALL INT、MEDIUM INT、 INT、 BIG INT

浮点数类型:FLOAT、DOUBLEDECIMAL

字符串类型:CHAR、VARCHARBINARY、VARBINARYTINY TEXT、TEXT、MEDIUM TEXT、LONGTEXTTINY BLOB、BLOB、MEDIUM BLOB、LONG BLOB

日期类型:Date、Time、DateTime、TimeStamp、Year

其他数据类型:ENUM、SET、Geometry、Point、MultiPoint、LineString、MultiLineString、Polygon、GeometryCollection等

注意:关于Mysql中常用的数据类型的长度问题,一般来说,在mysql里面,只有数值型和字符型的长度有意义,可以由程序员根据实际业务需求定义,但不允许超过类型最大长度;其他的,大文本text/blob 时间 date time datetime timestamp 的长度都没有意义,这些特定类型的长度由数据库系统定义,不由用户定义,使用的时候直接指定为0.

三、具体数据类型(面试重点,记住那些类型 + 类似类型的区别 + 开发选用原则)

3.1 整型七种

整型七种:bit bool 五种int(tinyInt smallInt mediumInt Int BigInt).

MySQL数据类型 含义(有符号)

tinyint(m) 1个字节 范围(-128~127) 或者 0-256 所以是8bit,1字节

smallint(m) 2个字节 范围(-32768~32767) 或者 0-65536 所以是16bit 2字节

mediumint(m) 3个字节 范围(-8388608~8388607)

int(m) 4个字节 范围(-2147483648~2147483647)

bigint(m) 8个字节 范围(±9.22*10的18次方)

对于五个int,取值范围如果加了unsigned,则最大值翻倍,如tinyint unsigned的取值范围为(0~256)。

int(m)里的m是表示SELECT查询结果集中的显示宽度,并不影响实际的取值范围,没有影响到显示的宽度,不知道这个m有什么用。

3.2 浮点型三种

3.2.1 浮点型(float和double)

浮点型三种:float double decimal

MySQL数据类型 含义
float(m,d) 单精度浮点型 8位精度(4字节) m总个数,d小数位
double(m,d) 双精度浮点型 16位精度(8字节) m总个数,d小数位

mysql中,设一个字段定义为float(6,3),总位数是6位,小数位是3位,所以整数位是6-3=3位,

解释:如果插入一个数123.45678,实际数据库里存的是123.456
第一,明确要求:总位数是6,小数位是3,则整数位是6-6=3,所以,要求小数位是3,整数位3;
第二,是否满足要求,这里整数位满足要求,小数位不满足要求,
第三,以总位数6位保存,在不改变数值的前提下:由于小数位不满足要求,只能牺牲小数位,整数位不变,存储为123.456

解释:如果插入数12.123456,存储的是12.1234,
第一,明确要求:总位数是6,小数位是3,则整数位是6-6=3,所以,要求小数位是3,整数位3;
第二,是否满足要求,这里整数位满足要求,小数位不满足要求,
第三,以总位数6位保存,在不改变数值的前提下:由于小数位不满足要求,只能牺牲小数位,整数位不变,存储为12.1234

解释:如果插入12.12,存储的是12.1200
第一,明确要求:总位数是6,小数位是3,则整数位是6-6=3,所以,要求小数位是3,整数位3,
第二,是否满足要求:这里12.12 整数位和小数位都满足,
第三,以总位数6位保存,在不改变数值的前提下:只能在整数位前面加0后小数位后面加0,在整数位前面加0没有意义,所以在小数位后面加0,为12.1200

3.2.2 定点数

浮点型在数据库中存放的是近似值,而定点类型在数据库中存放的是精确值。

decimal(m,d) 参数m<65 是总个数,d<30且 d<m 是小数位。

注意:项目中涉及到货币运算,既有小数点又要保证绝对精准,mysql中两种方式处理
方案一:使用整型,交给后端处理,除以100,mysql使用整型保证绝对精准,后端除以100得到小数点
方案二:mysql处理,直接使用decimal(m,d)类型,既有小数点又保证绝对精准

3.3 字符串类型 10种

3.3.1 字符串(char,varchar,_text)

MySQL数据类型 含义
char(n) 固定长度,最多255个字符
varchar(n) 可变长度,最多65535个字符
tinytext 可变长度,最多255个字符 最多2的8次方-1个字符 1个字节 8bit
text 可变长度,最多65535个字符 最多2的16次方-1个字符 2个字节 16bit
mediumtext 可变长度,最多2的24次方-1个字符 3字节 24bit
longtext 可变长度,最多2的32次方-1个字符 4字节 32bit

字符型12种
(1) char varchar binary varbinary 因为固定长度,所以程序员新建字段时需要指定长度,但是指定不能超过系统设置
(2) text四种 tinyText text mediumText longtext 因为可变长度,所以程序员新建字段时,不需要指定长度,单子自动扩展有上限
(3) blob四种 tinyblob blob mediumblob longblob 因为可变长度,所以程序员新建字段时,不需要指定长度,单子自动扩展有上限

char和varchar(高频考点):
(1) 使用时,char末尾不能有空格,varchar末尾可以有空格
char类型存储的字符串末尾不能有空格,varchar没有这个要求
解释/为什么?:char(n) 使用时,若存入字符数小于n,则以空格补于其后,查询之时再将空格去掉。
(2) 使用时,char是固定长度,varchar是可变长度
char固定长度,char(4)不管是存入几个字符,都将占用4个字节,
varchar是可变长度,varchar(4),存入1个字符将占用2个字节,存入2个字符将占用3个字节,存入3个字符将占用4个字节。
解释:是存入的实际字符数+1个字节(当n<=255)或2个字节(当n>255),
(3) char类型的字符串检索速度要比varchar类型的快。
解释:char固定长度,varchar是可变长度。

varchar和text:
1.创建字段时指定长度n:
1.1 创建字段时,varchar可指定n,text不能指定;
1.2 使用字段时,内部存储varchar是存入的实际字符数+1个字节(n<=255)或2个字节(n>255),text是实际字符数+2个字节。
2.默认值:varchar可以设置默认值,text类型不能有默认值。
3.检索速度:varchar可直接创建索引,text创建索引要指定前多少个字符。varchar查询速度快于text,在都创建索引的情况下,text的索引似乎不起作用。

选用:字符串检索速度 char > varchar > text
char 固定长度 +索引
varchar 可变长度 +索引
text 可变长度+索引
存储文本大小 char < varchar< text
小结:三种字符串类型选用,小字符串用char,比如保存密码,提示用户上限为255,业务上大一点就用varchar,比如备注信息,提示用户上限为65535,大文本就用text

3.3.2 二进制数据(_Blob)

blob和text区别(都是字符串类型)
1._BLOB和_text存储方式不同,_TEXT以文本方式存储,英文存储区分大小写,而_Blob是以二进制方式存储,不分大小写。
2._BLOB存储的数据只能整体读出。
3._TEXT可以指定字符集,_BLOB不用指定字符集。

3.4 日期时间类型 5种

MySQL数据类型 含义
date 日期 ‘2008-12-2’
time 时间 ‘12:25:36’
datetime 日期时间 ‘2008-12-2 22:06:44’
timestamp 自动存储记录修改时间

timestamp最重要的用途
若定义一个字段为timestamp,这个字段里的时间数据会随其他字段修改的时候自动刷新,所以这个数据类型的字段可以存放这条记录最后被修改的时间(金手指:这是timestamp在开发的时候最重要的用途)。

3.5 附:数据类型的属性

MySQL关键字 含义
NULL 数据列可包含NULL值
NOT NULL 数据列不允许包含NULL值
DEFAULT 默认值
PRIMARY KEY 主键
AUTO_INCREMENT 自动递增,适用于整数类型
UNSIGNED 无符号
CHARACTER SET name 指定一个字符集

四、所有数据类型的长度和范围(面试重点,记住那些类型 + 类似类型的区别 + 开发选用原则)

各数据类型及字节长度一览表:

4.1 整型 7种

数据类型 字节长度 范围或用法
Bit/Bool 1 无符号[0,255],有符号[-128,127],备注:BIT和BOOL布尔型都占用1字节,因为最小一个字节,不存在半个字节的
TinyInt 1 整数[0,255]
SmallInt 2 无符号[0,65535],有符号[-32768,32767]
MediumInt 3 无符号[0,224-1],有符号[-223,2^23-1]]
Int 4 无符号[0,232-1],有符号[-231,2^31-1]
BigInt 8 无符号[0,264-1],有符号[-263 ,2^63 -1]

4.2 浮点型 3种

数据类型 字节长度 范围或用法
Float(M,D) 4 单精度浮点数。注意:这里的D是精度,如果D<=24则为默认的FLOAT,如果D>24则会自动被转换为DOUBLE型。
Double(M,D) 8 双精度浮点。
Decimal(M,D) M+1或M+2 未打包的浮点数,用法类似于FLOAT和DOUBLE

4.3 字符串类型 12种

数据类型 字节长度 范围或用法
Char(M) M字节(新建字段的时候确定) 定长字符串。
VarChar(M) M字节(新建字段的时候确定) 变长字符串,要求M<=255
Binary(M) M字节(新建字段的时候确定) 类似Char的二进制存储,特点是插入定长不足补0
VarBinary(M) M字节(新建字段的时候确定) 类似VarChar的变长二进制存储,特点是定长不补0
Tiny Text Max:255 大小写不敏感 1字节 2的8次方
Text Max:64K 大小写不敏感 2字节 2的16次方
Medium Text Max:16M 大小写不敏感 3字节 2的24次方
Long Text Max:4G 大小写不敏感 4字节 2的32次方
TinyBlob Max:255 大小写敏感 1字节 2的8次方
Blob Max:64K 大小写敏感 2字节 2的16次方
MediumBlob Max:16M 大小写敏感 3字节 2的24次方
LongBlob Max:4G 大小写敏感 4字节 2的32次方

对于12种字符串类型
char varchar 和 binary varbinary
前者是字符串,后者是二进制
text 和 blob
text是大小写不敏感,blob是大小写敏感

4.4 时间类型 3种

数据类型 字节长度 范围或用法
Date 3 以YYYY-MM-DD的格式显示,比如:2009-07-19
Time 3 以HH:MM:SS的格式显示。比如:11:22:30
Date Time 8 以YYYY-MM-DD HH:MM:SS的格式显示,比如:2009-07-19 11:22:30
TimeStamp 4 以YYYY-MM-DD的格式显示,比如:2009-07-19
Year 1 以YYYY的格式显示。比如:2009

4.5 其他类型(记住Enum和Set就好)

数据类型 字节长度 范围或用法
Enum 16bit 两个字节,所以,最大可达65535个不同的枚举值
Set 8bit 一个字节,所以,最大可达64个不同的值
Geometry
Point
LineString
Polygon
MultiPoint
MultiLineString
MultiPolygon
GeometryCollection

五、选择数据类型的基本原则(面试重点,一定从存储引擎底层解释,拉高逼格)

5.1 数据类型从小原则

满足业务需求条件下从小原则,第一,类型小占用字节少,在大数据行记录下很重要,第二,从小一般检索更快:在指定数据类型的时候一般是采用从小原则,比如能用TINY INT的最好就不用INT,能用FLOAT类型的就不用DOUBLE类型,这样会对MYSQL在运行效率上提高很大,尤其是大数据量测试条件下。

5.2 使用适合存储引擎

选择原则:根据选定的存储引擎,确定如何选择合适的数据类型。(即先确定存储引擎,再确定数据结构)

下面的选择方法按存储引擎分类:

MyISAM 数据存储引擎和数据列:MyISAM类型的数据表,最好使用固定长度(CHAR)的数据列代替可变长度(VARCHAR)的数据列。

MEMORY存储引擎和数据列:MEMORY类型的数据表,目前都使用固定长度的数据行存储,因此无论使用CHAR或VARCHAR列都没有关系。两者都是作为CHAR类型处理的。

InnoDB 存储引擎和数据列:建议使用 VARCHAR类型。

对于InnoDB数据表,内部的行存储格式没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),因此在本质上,使用固定长度的CHAR列不一定比使用可变长度VARCHAR列简单。因而,主要的性能因素是数据行使用的存储总量。由于CHAR平均占用的空间多于VARCHAR,因 此使用VARCHAR来最小化需要处理的数据行的存储总量和磁盘I/O是比较好的。

5.3 把握相似数据类型的区别:char与varchar

CHAR和VARCHAR类型类似,但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。

第一个区别,char类型是固定长度,varchar类型是可变长度

下面的表显示了将各种字符串值保存到CHAR(4)和VARCHAR(4)列后的结果,说明了CHAR和VARCHAR之间的差别:

char(4)存储需求varchar(4)存储需求
‘’’ ’永远都是指定字节数,这里永远都是4个字节‘’1个字节 (存入的实际字符数+1个字节(n<=255)或2个字节(n>255))
‘ab’'ab ’4个字节‘ab’3个字节
‘abcd’‘abcd’4个字节‘abcd’5个字节
‘abcdefgh’‘abcd’4个字节‘abcd’5个字节

请注意上表中最后一行的值只适用不使用严格模式时;如果MySQL运行在严格模式,超过列长度不的值不保存,并且会出现错误。

第二个区别,char类型默认不能存储空格

从CHAR(4)和VARCHAR(4)列检索的值并不总是相同,因为检索时从CHAR列删除了尾部的空格。通过下面的例子说明该差别:

mysql> CREATE TABLE vc (v VARCHAR(4), c CHAR(4));  // 新建一个表,两个列,一个varchar,一个char
Query OK, 0 rows affected (0.02 sec)
 
mysql> INSERT INTO vc VALUES ('ab  ', 'ab  ');  // 插入值  'ab  '  char类型末尾的空格会删去,varchar类型末尾空格不会删去
Query OK, 1 row affected (0.00 sec)
 
mysql> SELECT CONCAT(v, '+'), CONCAT(c, '+') FROM vc;   // 你看,char类型的字段,末尾的空格被舍去了
+----------------+----------------+
| CONCAT(v, '+') | CONCAT(c, '+') |
+----------------+----------------+
| ab  +          | ab+            |
+----------------+----------------+
1 row in set (0.00 sec)

5.4 把握相似数据类型的区别:text和blob

在使用text和blob字段类型时要注意以下几点,以便更好的发挥数据库的性能。

① 删除Blob和Text类型的字段值留下空洞,以后填入这些空洞记录长度不同,定期使用 OPTIMIZE TABLE 进行碎片整理。

BLOB和TEXT值也会引起自己的一些问题,特别是执行了大量的删除或更新操作的时候。删除这种值会在数据表中留下很大的"空洞",以后填入这些"空洞"的记录可能长度不同,为了提高性能,建议定期使用 OPTIMIZE TABLE 功能对这类表进行碎片整理.

② 使用合成的(synthetic)索引

合成的索引列在某些时候是有用的。

比如:

第一,得到散列字段:根据其它的列的内容建立一个散列值,并把这个值存储在单独的数据列中。接下来你就可以通过检索散列值找到数据行了。

局限(合成索引的局限):这种技术只能用于精确匹配的查询(散列值对于类似<或>=等范围搜索操作符 是没有用处的)。

第二,生成散列值的方式:我们可以使用MD5()函数生成散列值,也可以使用SHA1()或CRC32()生成散列值,或者使用自己的应用程序逻辑来生成散列值。请记住数值型散列值可以很高效率地存储。

注意(散列字段的存储):如果散列算法生成的字符串带有尾部空格,就不要把它们存储在CHAR或VARCHAR列中,它们会受到尾部空格去除的影响。

第三,合成的散列索引对于那些BLOB或TEXT数据列特别有用。用散列标识符值查找的速度比搜索BLOB列本身的速度快很多。

③ 在不必要的时候避免检索大型的BLOB或TEXT值(上一条告诉我们使用合成散列索引)。

在不必要的时候避免检索大型的BLOB或TEXT值。例如,SELECT *查询就不是很好的想法,除非你能够确定作为约束条件的WHERE子句只会找到所需要的数据行。否则,你可能毫无目的地在网络上传输大量的值。这也是 BLOB或TEXT标识符信息存储在合成的索引列中对我们有所帮助的例子。你可以搜索合成索引列,决定那些需要的数据行,然后从合格的数据行中检索BLOB或 TEXT值。

④ 把BLOB或TEXT列分离到单独的表中。

把BLOB或TEXT列分离到单独的表中。在某些环境中,如果把这些数据列移动到第二张数据表中,可以让你把原数据表中 的数据列转换为固定长度的数据行格式,那么它就是有意义的。这会减少主表中的碎片,使你得到固定长度数据行的性能优势。它还使你在主数据表上运行 SELECT *查询的时候不会通过网络传输大量的BLOB或TEXT值。

5.5 把握相似数据类型的区别:浮点数与定点数

为了能够引起大家的重视,在介绍浮点数与定点数以前先让大家看一个例子:

mysql> CREATE TABLE test (c1 float(10,2),c2 decimal(10,2));   //新建表
Query OK, 0 rows affected (0.29 sec)

mysql> insert into test values(131072.32,131072.32);   // 表中插入数据
Query OK, 1 row affected (0.07 sec)

mysql> select * from test;
+-----------+-----------+
| c1        | c2        |
+-----------+-----------+
| 131072.31 | 131072.32 |
+-----------+-----------+
1 row in set (0.00 sec)

从上面的例子中我们看到c1列的值由131072.32变成了131072.31,这就是浮点数的不精确性造成的。

浮点数和定点数
定义
在mysql中float、double(或real)是浮点数,decimal(或numberic)是定点数。
浮点数相对于定点数的优点
使用同样是字节数:在长度一定的情况下,浮点数能够表示更大的数据范围;
浮点数相对于定点数的缺点
引起精度问题。

mysql中,浮点数精度问题引起的三个注意点:
1、避免浮点数做货币:对货币等对精度敏感的数据,应该用定点数表示或存储;
2、避免浮点数的比较:编程中,如果用到浮点数,要特别注意误差问题,并尽量避免做浮点数比较;
3、浮点数的特殊值:要注意浮点数中一些特殊值的处理。

六、面试金手指

面试考点
1、记住所以类型,每一个类型的含义;
2、类似类型的区别;
3、开发选用原则;

6.1 所有类型,每一个类型的含义(第三部分+第四部分)

6.1.1 整型类型

6.1.1.1 整型类型介绍

整数类型:BIT、BOOLTINY INT、SMALL INT、MEDIUM INT、 INT、 BIG INT

七种整型类型,没什么好说的,记住字节数:1字节、1字节、1字节、2字节、3字节、4字节、8字节
注意,在整型里面,先medium int,然后int,在字符串类型text和blob里面,先text再medium text,先blob再次medium bolb

6.1.2 浮点数类型

6.1.2.1 浮点数类型介绍

浮点数和定点数类型:FLOAT、DOUBLEDECIMAL

浮点数:
Float(M,D) 4字节 单精度浮点数。注意:这里的D是精度,如果D<=24则为默认的FLOAT,如果D>24则会自动被转换为DOUBLE型。
Double(M,D) 8字节 双精度浮点。
Decimal(M,D) M+1或M+2字节 未打包的浮点数,用法类似于FLOAT和DOUBLE

6.1.2.2 浮点数类型高级

金手指:float和double
浮点数以 8 位精度存储在 FLOAT 中,有四个字节。
浮点数以18位精度存储在 DOUBLE 中,有八个字节。

金手指:长度:CHAR_LENGTH 和 LENGTH 区别?
都是用来表示长度,但是,CHAR_LENGTH 是字符数,而 LENGTH 是字节数。Latin 字符的这两个数据是相同的,但是对于 Unicode 和其他编码,它们是不同的。

金手指:货币,decimal重要用法
项目中涉及到货币运算,既有小数点又要保证绝对精准,mysql中两种方式处理
方案一:使用整型,交给后端处理,除以100,mysql使用整型保证绝对精准,后端除以100得到小数点
方案二:mysql处理,直接使用decimal(m,d)类型,既有小数点又保证绝对精准

面试经典问题:mysql 里记录货币用什么字段类型好

NUMERIC 和 DECIMAL 类型被 Mysql 实现为同样的类型,这在 SQL92 标准允许。他们被用于保存值,该值的准确精度是极其重要的值,例如与金钱有关的数据。当声明一个类是这些类型之一时,精度和规模的能被(并且通常是)指定;点击这里有一套最全阿里面试题总结。

例如:

salary DECIMAL(9,2)

在这个例子中,9(precision)代表将被用于存储值的总的小数位数,而 2(scale)代表将被用于存储小数点后的位数。

因此,在这种情况下,能被存储在 salary 列中的值的范围是从-9999999.99 到 9999999.99。 在 ANSI/ISO SQL92 中,句法 DECIMAL§等价于 DECIMAL(p,0)。
同样,句法 DECIMAL 等价于 DECIMAL(p,0),这里实现被允许决定值 p。Mysql 当前不支持DECIMAL/NUMERIC 数据类型的这些变种形式的任一种。

这一般说来不是一个严重的问题,因为这些类型的主要益处得自于明显地控制精度和规模
的能力。

DECIMAL 和 NUMERIC 值作为字符串存储,而不是作为二进制浮点数,以便保存那些值的小数精度。

一个字符用于值的每一位、小数点(如果 scale>0)和“-”符号(对于负值)。如果 scale 是 0,
DECIMAL 和 NUMERIC 值不包含小数点或小数部分。

DECIMAL 和 NUMERIC 值得最大的范围与 DOUBLE 一样,但是对于一个给定的 DECIMAL 或 NUMERIC 列,实际的范围可由制由给定列的 precision 或 scale 限制。
当这样的列赋给了小数点后面的位超过指定 scale 所允许的位的值,该值根据 scale 四舍五入。

当一个 DECIMAL 或 NUMERIC 列被赋给了其大小超过指定(或缺省的)precision 和 scale 隐含的范围的值,Mysql 存储表示那个范围的相应的端点值。

6.1.3 字符串类型

6.1.3.1 字符串类型介绍

字符串类型:CHAR、VARCHARBINARY、VARBINARYTINY TEXT、TEXT、MEDIUM TEXT、LONGTEXTTINY BLOB、BLOB、MEDIUM BLOB、LONG BLOB

数据类型 字节长度 范围或用法
Char(M) M字节(新建字段的时候确定) 定长字符串。
VarChar(M) M字节(新建字段的时候确定) 变长字符串,要求M<=255
Binary(M) M字节(新建字段的时候确定) 类似Char的二进制存储,特点是插入定长不足补0
VarBinary(M) M字节(新建字段的时候确定) 类似VarChar的变长二进制存储,特点是定长不补0
Tiny Text Max:255 大小写不敏感 1字节 2的8次方
Text Max:64K 大小写不敏感 2字节 2的16次方
Medium Text Max:16M 大小写不敏感 3字节 2的24次方
Long Text Max:4G 大小写不敏感 4字节 2的32次方
TinyBlob Max:255 大小写敏感 1字节 2的8次方
Blob Max:64K 大小写敏感 2字节 2的16次方
MediumBlob Max:16M 大小写敏感 3字节 2的24次方
LongBlob Max:4G 大小写敏感 4字节 2的32次方

对于12种字符串类型
char varchar 和 binary varbinary
前者是字符串,后者是二进制
text 和 blob
text是大小写不敏感,blob是大小写敏感

6.1.3.2 字符串类型高级

char和varchar(高频考点):
1. 使用时,char末尾不能有空格,varchar末尾可以有空格
char类型存储的字符串末尾不能有空格,varchar没有这个要求
解释/为什么?:char(n) 使用时,若存入字符数小于n,则以空格补于其后,查询之时再将空格去掉。
2.使用时,char是固定长度,varchar是可变长度
char固定长度,char(4)不管是存入几个字符,都将占用4个字节,
varchar是可变长度,varchar(4),存入1个字符将占用2个字节,存入2个字符将占用3个字节,存入3个字符将占用4个字节。
解释:是存入的实际字符数+1个字节(当n<=255)或2个字节(当n>255),
3.char类型的字符串检索速度要比varchar类型的快。
解释:char固定长度,varchar是可变长度。

varchar和text:
1.创建字段时指定长度n:
1.1 创建字段时,varchar可指定n,text不能指定;
1.2 使用字段时,内部存储varchar是存入的实际字符数+1个字节(n<=255)或2个字节(n>255),text是实际字符数+2个字节。
2.默认值:varchar可以设置默认值,text类型不能有默认值。
3.检索速度:varchar可直接创建索引,text创建索引要指定前多少个字符。varchar查询速度快于text,在都创建索引的情况下,text的索引似乎不起作用。

选用
字符串检索速度 char > varchar > text
char 固定长度 +索引
varchar 可变长度 +索引
text 可变长度+索引
存储文本大小 char < varchar< text
小结:三种字符串类型选用,小字符串用char,比如保存密码,提示用户上限为255,业务上大一点就用varchar,比如备注信息,提示用户上限为65535,大文本就用text

blob和text区别(都是字符串类型)
1._BLOB和_text存储方式不同,
TEXT以文本方式存储,英文存储,对text值排序和比较时,区分大小写;
BlOB是以二进制方式存储,对blob值排序和比较时,不分大小写。
2._BLOB存储的数据只能整体读出。
3._TEXT可以指定字符集,_BLOB不用指定字符集。

【字符串类型】什么是非标准字符串类型?
以下是非标准字符串类型:TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT

6.1.4 日期类型

6.1.4.1 日期类型介绍

日期类型:Date、Time、DateTime、TimeStamp、Year

Date 3 以YYYY-MM-DD的格式显示,比如:2009-07-19
Time 3 以HH:MM:SS的格式显示。比如:11:22:30
Date Time 8 以YYYY-MM-DD HH:MM:SS的格式显示,比如:2009-07-19 11:22:30
TimeStamp 4 以YYYY-MM-DD的格式显示,比如:2009-07-19
Year 1 以YYYY的格式显示。比如:2009

6.1.4.2 日期类型高级

timestamp最重要的用途
若定义一个字段为timestamp,这个字段里的时间数据会随其他字段修改的时候自动刷新,所以这个数据类型的字段可以存放这条记录最后被修改的时间(金手指:这是timestamp在开发的时候最重要的用途)。

TIMESTAMP 在 UPDATE CURRENT_TIMESTAMP 数据类型上做什么?
第一,创建表时 TIMESTAMP 列用 Zero 更新。
第二,只要表中的其他字段发生更改,UPDATE CURRENT_TIMESTAMP 修饰符就将时间戳字段更新为当前时间。

【数据类型】如何在 Unix 和 Mysql 时间戳之间进行转换?
UNIX_TIMESTAMP 是从 Mysql 时间戳转换为 Unix 时间戳的命令
FROM_UNIXTIME 是从 Unix 时间戳转换为 Mysql 时间戳的命令

【时间类型】如果一个表有一列定义为 TIMESTAMP,将发生什么?
每当行被更改时,时间戳字段将获取当前时间戳。

6.1.5 其他类型

6.1.5.1 其他类型介绍

其他数据类型:ENUM、SET、Geometry、Point、MultiPoint、LineString、MultiLineString、Polygon、GeometryCollection等

Enum 16bit 两个字节,所以,最大可达65535个不同的枚举值
Set 8bit 一个字节,所以,最大可达64个不同的值

其中,ENUM 是一个字符串对象,用于指定一组预定义的值,并可在创建表时使用。
Create table size(name ENUM('Smail,‘Medium’,‘Large’);

6.1.6 附加

MySQL关键字 含义
NULL 数据列可包含NULL值
NOT NULL 数据列不允许包含NULL值
DEFAULT 默认值
PRIMARY KEY 主键
AUTO_INCREMENT 自动递增,适用于整数类型
UNSIGNED 无符号
CHARACTER SET name 指定一个字符集

6.2 开发选用原则(第五部分)

6.2.1 数据类型从小原则

满足业务需求条件下从小原则,第一,类型小占用字节少,在大数据行记录下很重要,第二,从小一般检索更快:在指定数据类型的时候一般是采用从小原则,比如能用TINY INT的最好就不用INT,能用FLOAT类型的就不用DOUBLE类型,这样会对MYSQL在运行效率上提高很大,尤其是大数据量测试条件下。

6.2.2 使用适合存储引擎

选择原则:根据选定的存储引擎,确定如何选择合适的数据类型。(即先确定存储引擎,再确定数据结构)

下面的选择方法按存储引擎分类:

MyISAM 数据存储引擎和数据列:MyISAM类型的数据表,最好使用固定长度(CHAR)的数据列代替可变长度(VARCHAR)的数据列。

MEMORY存储引擎和数据列:MEMORY类型的数据表,目前都使用固定长度的数据行存储,因此无论使用CHAR或VARCHAR列都没有关系。两者都是作为CHAR类型处理的。

InnoDB 存储引擎和数据列:建议使用 VARCHAR类型。

对于InnoDB数据表,内部的行存储格式没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),因此在本质上,使用固定长度的CHAR列不一定比使用可变长度VARCHAR列简单。因而,主要的性能因素是数据行使用的存储总量。由于CHAR平均占用的空间多于VARCHAR,因 此使用VARCHAR来最小化需要处理的数据行的存储总量和磁盘I/O是比较好的。

6.2.3 把握相似数据类型的区别:char与varchar

CHAR和VARCHAR类型类似,但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。

第一个区别,char类型是固定长度,varchar类型是可变长度

下面的表显示了将各种字符串值保存到CHAR(4)和VARCHAR(4)列后的结果,说明了CHAR和VARCHAR之间的差别:

char(4)存储需求varchar(4)存储需求
‘’’ ’永远都是指定字节数,这里永远都是4个字节‘’1个字节 (存入的实际字符数+1个字节(n<=255)或2个字节(n>255))
‘ab’'ab ’4个字节‘ab’3个字节
‘abcd’‘abcd’4个字节‘abcd’5个字节
‘abcdefgh’‘abcd’4个字节‘abcd’5个字节

请注意上表中最后一行的值只适用不使用严格模式时;如果MySQL运行在严格模式,超过列长度不的值不保存,并且会出现错误。

第二个区别,char类型默认不能存储空格

从CHAR(4)和VARCHAR(4)列检索的值并不总是相同,因为检索时从CHAR列删除了尾部的空格。通过下面的例子说明该差别:

mysql> CREATE TABLE vc (v VARCHAR(4), c CHAR(4));  // 新建一个表,两个列,一个varchar,一个char
Query OK, 0 rows affected (0.02 sec)
 
mysql> INSERT INTO vc VALUES ('ab  ', 'ab  ');  // 插入值  'ab  '  char类型末尾的空格会删去,varchar类型末尾空格不会删去
Query OK, 1 row affected (0.00 sec)
 
mysql> SELECT CONCAT(v, '+'), CONCAT(c, '+') FROM vc;   // 你看,char类型的字段,末尾的空格被舍去了
+----------------+----------------+
| CONCAT(v, '+') | CONCAT(c, '+') |
+----------------+----------------+
| ab  +          | ab+            |
+----------------+----------------+
1 row in set (0.00 sec)

6.2.4 把握相似数据类型的区别:text和blob

在使用text和blob字段类型时要注意以下几点,以便更好的发挥数据库的性能。

① 删除Blob和Text类型的字段值留下空洞,以后填入这些空洞记录长度不同,定期使用 OPTIMIZE TABLE 进行碎片整理。

BLOB和TEXT值也会引起自己的一些问题,特别是执行了大量的删除或更新操作的时候。删除这种值会在数据表中留下很大的"空洞",以后填入这些"空洞"的记录可能长度不同,为了提高性能,建议定期使用 OPTIMIZE TABLE 功能对这类表进行碎片整理.

② 使用合成的(synthetic)索引

合成的索引列在某些时候是有用的。

比如:

第一,得到散列字段:根据其它的列的内容建立一个散列值,并把这个值存储在单独的数据列中。接下来你就可以通过检索散列值找到数据行了。

局限(合成索引的局限):这种技术只能用于精确匹配的查询(散列值对于类似<或>=等范围搜索操作符 是没有用处的)。

第二,生成散列值的方式:我们可以使用MD5()函数生成散列值,也可以使用SHA1()或CRC32()生成散列值,或者使用自己的应用程序逻辑来生成散列值。请记住数值型散列值可以很高效率地存储。

注意(散列字段的存储):如果散列算法生成的字符串带有尾部空格,就不要把它们存储在CHAR或VARCHAR列中,它们会受到尾部空格去除的影响。

第三,合成的散列索引对于那些BLOB或TEXT数据列特别有用。用散列标识符值查找的速度比搜索BLOB列本身的速度快很多。

③ 在不必要的时候避免检索大型的BLOB或TEXT值(上一条告诉我们使用合成散列索引)。

在不必要的时候避免检索大型的BLOB或TEXT值。例如,SELECT *查询就不是很好的想法,除非你能够确定作为约束条件的WHERE子句只会找到所需要的数据行。否则,你可能毫无目的地在网络上传输大量的值。这也是 BLOB或TEXT标识符信息存储在合成的索引列中对我们有所帮助的例子。你可以搜索合成索引列,决定那些需要的数据行,然后从合格的数据行中检索BLOB或 TEXT值。

④ 把BLOB或TEXT列分离到单独的表中。

把BLOB或TEXT列分离到单独的表中。在某些环境中,如果把这些数据列移动到第二张数据表中,可以让你把原数据表中 的数据列转换为固定长度的数据行格式,那么它就是有意义的。这会减少主表中的碎片,使你得到固定长度数据行的性能优势。它还使你在主数据表上运行 SELECT *查询的时候不会通过网络传输大量的BLOB或TEXT值。

6.2.5 把握相似数据类型的区别:浮点数与定点数

为了能够引起大家的重视,在介绍浮点数与定点数以前先让大家看一个例子:

mysql> CREATE TABLE test (c1 float(10,2),c2 decimal(10,2));   //新建表
Query OK, 0 rows affected (0.29 sec)

mysql> insert into test values(131072.32,131072.32);   // 表中插入数据
Query OK, 1 row affected (0.07 sec)

mysql> select * from test;
+-----------+-----------+
| c1        | c2        |
+-----------+-----------+
| 131072.31 | 131072.32 |
+-----------+-----------+
1 row in set (0.00 sec)

从上面的例子中我们看到c1列的值由131072.32变成了131072.31,这就是浮点数的不精确性造成的。

浮点数和定点数
定义
在mysql中float、double(或real)是浮点数,decimal(或numberic)是定点数。
浮点数相对于定点数的优点
使用同样是字节数:在长度一定的情况下,浮点数能够表示更大的数据范围;
浮点数相对于定点数的缺点
引起精度问题。

mysql中,浮点数精度问题引起的三个注意点:
1、避免浮点数做货币:对货币等对精度敏感的数据,应该用定点数表示或存储;
2、避免浮点数的比较:编程中,如果用到浮点数,要特别注意误差问题,并尽量避免做浮点数比较;
3、浮点数的特殊值:要注意浮点数中一些特殊值的处理。

七、尾声

一般策略就是字符型使用varchar,对应服务端java中的String,数字类型使用bigint,对应服务端java中的Long,对于服务端java来说,原则上能用Long就不用Integer。

另外,关于Mysql中常用的数据类型的长度问题,一般来说,在mysql里面,只有数值型和字符型的长度有意义,可以由程序员根据实际业务需求定义,但不允许超过类型最大长度;其他的,大文本text/blob 时间 date time datetime timestamp 的长度都没有意义,这些特定类型的长度由数据库系统定义,不由用户定义,使用的时候直接指定为0

天天打码,天天进步!!!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
商品规格设计可以采用以下的 MySQL 数据库结构: 1. 商品规格 `specifications`: | 字段名 | 数据类型 | 描述 | | ------ | -------- | ---- | | id | int(11) | 商品规格ID,主键,自增 | | name | varchar(255) | 规格名称 | | created_at | datetime | 创建时间 | | updated_at | datetime | 更新时间 | 2. 商品规格选项 `specification_options`: | 字段名 | 数据类型 | 描述 | | ------ | -------- | ---- | | id | int(11) | 商品规格选项ID,主键,自增 | | specification_id | int(11) | 商品规格ID,外键 | | name | varchar(255) | 规格选项名称 | | created_at | datetime | 创建时间 | | updated_at | datetime | 更新时间 | 3. 商品规格与商品的关联 `product_specifications`: | 字段名 | 数据类型 | 描述 | | ------ | -------- | ---- | | id | int(11) | 商品规格关联ID,主键,自增 | | product_id | int(11) | 商品ID,外键 | | specification_id | int(11) | 商品规格ID,外键 | | specification_option_id | int(11) | 商品规格选项ID,外键 | | created_at | datetime | 创建时间 | | updated_at | datetime | 更新时间 | 通过以上的结构设计,可以实现商品规格的制作。其,商品规格 `specifications` 示商品规格的名称,例如颜色、尺寸等;商品规格选项 `specification_options` 示商品规格的选项,例如红色、白色、L码、XL码等;商品规格与商品的关联 `product_specifications` 示商品与规格选项的关系。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

祖母绿宝石

打赏一下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值