无论是在小得可怜的免费数据库空间或是大型电子商务网站 合理的设计表结构 充分利用空间是十分必要的 这就要求我们对数据库系统的常用数据类型有充分的认识 下面我就将我的一点心得写出来跟大家分享
一 数字类型
数字类型按照我的分类方法分为三类 整数类 小数类和数字类
我所谓的 数字类 就是指DECIMAL和NUMERIC 它们是同一种类型 它严格的说不是一种数字类型 因为他们实际上是将数字以字符串形式保存的 他的值的每一位(包括小数点)占一个字节的存储空间 因此这种类型耗费空间比较大 但是它的一个突出的优点是小数的位数固定 在运算中不会 失真 所以比较适合用于 价格 金额 这样对精度要求不高但准确度要求非常高的字段
小数类 即浮点数类型 根据精度的不同 有FLOAT(单精度)和DOUBLE(双精度)两种 它们的优势是精确度 FLOAT可以表示绝对值非常小 小到约 E ( 小数点后面有 个零)的小数 而DOUBLE更是可以表示绝对值小到约 E ( 小数点后面有 个零)的小数 FLOAT类型和DOUBLE类型占用存储空间分别是 字节和 字节 如果需要用到小数的字段 精度要求不高的 当然用FLOAT了!可是说句实在话 我们 民用 的数据 哪有要求精度那么高的呢?这两种类型至今我没有用过——我还没有遇到适合于使用它们的事例
用的最多的 最值得精打细算的 是整数类型 从只占一个字节存储空间的TINYINT到占 个字节的BIGINT 挑选一个 够用 并且占用存储空间最小的类型是设计数据库时应该考虑的 TINYINT SMALLINT MEDIUMINT INT和BIGINT占用存储空间分别为 字节 字节 字节 字节和 字节 就无符号的整数而言 这些类型能表示的最大整数分别为 和 如果用来保存用户的年龄(举例来说 数据库中保存年龄是不可取的) 用TINYINT就够了 九城的《纵横》里 各项技能值 用SMALLINT也够了 如果要用作一个肯定不会超过 行的表的AUTO_INCREMENT的IDENTIFY字段 当然用 MEDIUMINT 不用 INT 试想 每行节约一个字节 行可以节约 兆多呢!
二 日期时间类型
日期和时间类型比较简单 无非是 DATE TIME DATETIME TIMESTAMP和YEAR等几个类型 只对日期敏感 而对时间没有要求的字段 就用DATE而不用DATETIME是不用说的了 单独使用时间的情况也时有发生——使用TIME 但最多用到的还是用DATETIME 在日期时间类型上没有什么文章可做 这里就不再详述
三 字符(串)类型
不要以为字符类型就是 CHAR !CHAR和VARCHAR的区别在于CHAR是固定长度 只要你定义一个字段是CHAR( ) 那么不论你存储的数据是否达到了 个字节 它都要占去 个字节的空间 而VARVHAR则是可变长度的 如果一个字段可能的值是不固定长度的 我们只知道它不可能超过 个字符 把它定义为 VARCHAR( )是最合算的 VARCHAR 类型的实际长度是它的值的(实际长度+ ) 为什么 + 呢?这一个字节用于保存实际使用了多大的长度呀!从这个 + 中也应该看到 如果一个字段 它的可能值最长是 个字符 而多数情况下也就是用到了 个字符时 用VARCHAR就不合算了 因为在多数情况下 实际占用空间是 个字节 比用CHAR( )还多占用一个字节!
举个例子 就是一个存储股票名称和代码的表 股票名称绝大部分是四个字的 即 个字节 股票代码 上海的是六位数字 深圳的是四位数字 这些都是固定长度的 股票名称当然要用 CHAR( ) 股票代码虽然是不固定长度 但如果使用VARVHAR( ) 一个深圳的股票代码实际占用空间是 个字节 而一个上海的股票代码要占用 个字节!考虑到上海的股票数目比深圳的多 那么用VARCHAR( )就不如CHAR( )合算了
虽然一个CHAR或VARVHAR的最大长度可以到 我认为大于 的CHAR是几乎用不到的——很少有大于 个字节长度的固定长度的东东吧?不是固定长度的就用VARCHAR!大于 的VARCHAR也是几乎用不到的——比这更大的用TEXT就好了 TINYTEXT 最大长度为 占用空间也是(实际长度+ ) TEXT 最大长度 占用空间是(实际长度+ ) MEDIUMTEXT 最大长度 占用空间是(实际长度+ ) LONGTEXT 最大长度 占用空间是(实际长度+ ) 为什么 + ? + ? + ? + ?你要是还不知道就该打PP了 这些可以用在论坛啊 新闻啊 什么的 用来保存文章的正文 根据实际情况的不同 选择从小到大的不同类型
四 枚举和集合类型
枚举(ENUM)类型 最多可以定义 种不同的字符串从中做出选择 只能并且必须选择其中一种 占用存储空间是一个或两个字节 由枚举值的数目决定 集合(SET)类型 最多可以有 个成员 可以选择其中的零个到不限定的多个 占用存储空间是一个到八个字节 由集合可能的成员数目决定
举个例子来说 在SQLServer中 你可以节约到用一个Bit类型来表示性别(男/女) 但MySQL没有Bit 用TINTINT?不 可以用ENUM( 帅哥 美眉 )!只有两种选择 所以只需一个字节——跟TINYINT一样大 但却可以直接用字符串 帅哥 和 美眉 来存取 真是太方便啦!
lishixinzhi/Article/program/MySQL/201311/29648当面对巨大的数据表的时候,至少有一件事情是确定的,表太大了以至于每次查询的时候我们没法做全表扫描。而这个时候也没法使用索引,或者说索引意义不大,更不用说索引的维护代价和空间占用非常高。如果是依赖索引,会导致大量的碎片和低聚集度的数据,这会导致查询的时候有上千次的随机 I/O 访问而导致宕机。这种情况下一般只会使用1-2个索引,而不会更多。这种情况下,有两个可行的选项:查询必须从数据表的指定的部分顺序查找或者是期望的部分数据及其索引与服务器的内存匹配。
需要再次重申:在存储空间过大时,除非索引覆盖了整个查询,否则二叉树索引就无法发挥作用。服务端需要查找数据表的一整行数据,并且会在一个大空间跨度里执行随机 I/O *** 作,这会导致查询响应时间无法接受。而维护索引(磁盘空间,I/O *** 作)的代价同样很高。
而这是分区能够解决的问题。这其中的关键就是分区是索引的一个初级形式,它的负荷低并且能够让我们从临近的数据中获取结果。这种情形下,我们可以依次扫描相邻的数据或者是将临近的数据加载到内存进行检索。分区之所以负荷低是因为它并没有指针指向对应的数据行,也不需要被更新。分区并不精确地将数据按行划分,也没有涉及到所谓的数据结构。实际上,分区相当于对数据进行了分类。
对于大数据表,有两种策略进行分区:
两种分区策略是基于两个关键假设:在查询的时候可以通过过滤分区缩小查找范围,且分区自身的代价不高。然而,这两个假设未必总是有效,下面是可能遇到的问题:
如上所述,分区并不是完美解决方案,目前版本的 MySQL还有一些其他的约束:
当然,随着 MySQL 版本的更新迭代,对分区的支持也越来越好,并且很多分区的问题都得到了修复。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)