Mysql的schema和数据类型优化

1.     选择优化的数据类型:

--------遵循下面几个简单的原则--------:

    1. 更小的通常更好:

 一般情况下,尽量使用可以正确存储数据的最小数据类型。更小的通常更快,因为他们占用更少的的磁盘,内存和CPU缓存,处理时需要的CPU周期更短。

 2. 简单就好:

 简单的数据类型需要更少的CPU周期。例如整形比字符串操作代价更低,因为字符串和校对规则使字符串比整形更复杂。比如:应该是用mysql内建的类型(date, time,  datatime)而不是字符串来存储日期和时间。使用整形来存储IP地址。

 3. 尽量避免null

 很多表都包含NULL(空值)的列,即使应用程序不需要保存null也是如此,因为列的默认值是null,通常情况下,最好指定为NOT NULL,除非真的需要存储null值。

         如果查询中包含为NULL的列,对MySQL来说更难优化,因为NULL的列使得索引,索引统计和值比较都更复杂。

==============================数据类型优化================================

 1.1     整数类型:

         可以使用以下几种类型存储: TINYINT, SMALLINT,MEDIUMINT, INT, BIGINT。他们分别使用8,16, 24, 32, 64位存储空间。整数类型有可选的UNSIGNED属性,表示不允许负值,这大致可以使正数的上限提高一倍,例如TINYINT UNSIGNED可以存储的范围是0 ~ 255, 而TINYINT的存储范围是-128 ~ 127。他们使用的存储空间相同,具有相同的性能。

 MySQL可以为整数类型指定宽度,例如INT(11), 对大多数应用是没有意义的。它不会限制值得合法范围,只是规定了MySQL的一些交互工具(例如MySQL的命令行客户端)用来显示字符的个数。对于存储和计算来说,INT(1)和INT(20)是相同的。

 1.2. 实数类型:

         带有小数部分的数字。然后,它们不只是为了存储小数部分,也可以使用DECIMAL存储比BIGINT还大的正数。

DECIMAL是定点长度,FLOAT(占4个字节)和DOUBLE(占8个字节)是浮点。建议只指定数据类型,不指定精度。

         因为需要额外的空间和计算开销,所以应该尽量只在对小数进行精确计算的时候使用DECIMAL--例如存储财务数据。但是在数据量大的时候,可以使用考虑使用BIGINT来代替DECIMAL,将需要存储的货币单位根据小数的位数乘以相应的倍数即可。假如存储财务的数据精确到万分之一,这可以把所有金额乘以一百万,然后将计算出来的数存储在BIGINT里,这样可以同时避免浮点存储计算不精确和DECIMAL精确计算代价高的问题。

1.3.     字符串类型:

          1.3.1: VARCHAR :

VARCHAR 和 CHAR是主要的字符串类型, 不过,很难精确地解释这些值是如何存储在磁盘和内存中的,因为这跟存储引擎的具体实现有关。存储引擎存储CHAR 和 VARCHAR值得方式在内存中和磁盘中可能不一样,所以MySQL服务器从存储引擎读出的值可能需要转换为另一种存储格式。


                   VARCHAR类型,用于存储可变长字符串,是最常见的数据类型。比定长类型更加节省空间,当然当你的MySQL的表使用ROW_FORMAT=FIXED创建的话,每一行都会使用定长存储,造成空间浪费。

                   VARCHAR需要 1 或 2 个额外字节来记录字符串的长度。如果列的最大长度小于或等于255字节,则使用1个字节来记录表示,否则使用2个。

                   VARCHAR虽然节省了空间,但是在UPDATE时,可能使行变的比原来更长,这就导致了额外的工作。如果一个行占用的空间增长,并且页内没有更多空间可以存储,这种情况下不同的引擎处理方式不一样。例如:MyISAM会将行拆成不同片段存储,InnoDB则需要分裂页来使行可以放进页内。

                   下面这些情况使用VARCHAR是合适的:

                    1.字符串的最大长度比平均长度大很多。 2.列的更新很少,所以碎片不是问题。 3.使用了像UTF-8这样复杂的字符集,每个字符都使用不同的字节数进行存储。


 在MySQL5.0或者更高版本中,MySQL回存储和检索时会保留末尾的空格。但在4.1之前的版本中会删除末尾的空格。

         

         1.3.2: CHAR:

                   CHAR类型是定长的。存储CHAR的时候,MySQL会删除所有末尾的空间。

                   CHAR适合存储很短的字符串,或者所有值都接近同一个长度。例如,CHAR非常适合存储密码的MD5值,因为这是一个定长的值。对于经常变更的数据,CHAR也比VARCHAR更好,因为定长的CHAR不容易产生碎片。对于非常短的列,CHAR比VARCHAR在存储上也更有效率。例如CHAR(1)来存储只有Y和N的值,如果采用单字节字符集只需要一个字节,但是VARCHAR(1)却需要两个,因为需要记录长度的额外字节。

 使用VARCHAR(5)和 VARCHAR(200)来存储‘hello’的空间开销是一样的。但是事实证明更短的列有很大的优势,更长的列会消耗更多的内存。因为MySQL通常会分配固定大小的内存块来保存内部值,最差的情况会导致MySQL分配200位来存储临时表和排序。

          1.3.3: BLOB 和 TEXT:

                    都是用来存储很大的数据而设计的字符串类型,分别采用二进制 和 字符串方式存储。

                    与其他类型不同,MySQL会把每个BLOB 和 TEXT当做独立的对象进行处理。当BLOB 和 TEXT 值太大时,InnoDB会使用专门的 “外部”存储区域来进行存储,此时每个值在行内需要 1 ~ 4个字节来存储一个指针,然后在外部存储区域存储实际的值。

                   BLOB 和 TEXT 唯一的不同就是,BLOB存储的是二进制数据,没有排序规则或字符集,而TEXT类型有字符集和排序规则。

 MySQL对BLOB和TEXT列进行排序的时候,只对每个列的最前max_sort_length字节而不是整个字符串进行排序。如果想减少排序的字符串,可以减少max_sort_length的配置,或者使用ORDER BY SUSBTRING(column, length)。

                     MySQL不能对BLOB 和 TEXT列的全部长度进行索引。 

  1.4      使用枚举类型代替字符串类型:

                   很少用。

  1.5      日期和时间类型:

                   MySQL可以使用许多类型来保存日期和时间值。例如YEAR和DATE。MySQL能存储的最小时间粒度是秒,但是MySQL也可以使用微妙级的粒度进行临时运算。


         1.5.1     DATETIME类型:

                   这个类型能保存的值得范围,从1001年到9999年,精度为妙。他把日期封装到格式为YYYYMMDDHHMMSS的整数中,与时区无关。使用8个字节存储空间。默认情况下MySQL以一种可排序的,无歧义的格式显示DATETIME值,例如“2008-01-16 22:37:08”。这是ANSI标准定义的日期和时间表示方法。


          1.5.2     TIMESTAMP类型:

保存了从1970年1月1日午夜(格林尼治标准时间)以来的秒数,和UNIX时间戳相同。TIMESTAMP只使用了4个字节的存储空间,因此范围比DATETIME小得多。只能表示1970年到2038年。MySQL提供了FROM_UNIXTIME()函数把Unix时间戳转换为日期,并提供了UNIX_TIMESTAMP()函数把日起转为Unix的时间戳。

  TIMESTAMP的显示和时区有关。同一个时间戳,在不同的时区显示的值不一样。TIMESTAMP默认不为NULL。不推荐把时间戳保存为整数。

 timestamp只使用datetime一半的存储空间。

   1.6     位数据类型:

               很少使用。

   1.7:     反范式的优点和缺点:

                   反范式化的schema都在一张表中,可以很好的避免关联。

                   如果不需要关联表,则对大部分查询最差的情况(即使没有使用索引,是全表扫描)。当数据比内存大时这可能要比关联要快得多,因为这样避免了随机IO。(全表扫描的话基本都是顺序IO,但也不是100%,和存储引擎有关)

  1.8:   范式化的优点和缺点:

                   当为性能问题需求帮助时,经常会被建议使用schema进行范式化设计,尤其是写密集的场景

范式化带来的好处:

                        1.范式化的更新操作通常比反范式化要快。

                        2.当数据较好的范式化时,就只有很少或者没有重复数据,所以只需要修改更少的数据。

                        3.范式化的表通常比较小,可以更好的放在内存里,所以执行操作也很快。

                        4.很少有多余的数据,意味着检索表数据的时候更少需要distinct或者group by语句。

                   坏处:

                        1.通常需关联。稍微复杂的语句可能需要关联很多张表,代价比较昂贵,而且会使一些索引策略失效。例如:范式化可能将列存放在不同的表中,而这些列如果在一个表中本可以属于同一个索引。

MySQL设计原则总结:


          1.     尽量避免过度设计,例如导致极其复杂的查询schema设计,或者很多列的表设计。

          2.     使用小而简单的合适数据类型,尽量避免使用NULL值。

          3.     尽量使用相同的数据类型来存储相似或者相关的数据,尤其是关联查询中使用的列。

          4.     注意可变长字符串,其在临时表和排序时可能导致悲观的按最大长度分配内存。

          5.     尽量使用整形定义标识列。

6.  避免使用MySQL已经遗弃的特性,例如指定浮点数的精度,或者整数的显示宽度。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容