当前位置: 首页 > news >正文

河南省建设人才信息网站西安便宜的网站建设

河南省建设人才信息网站,西安便宜的网站建设,九江百度公司,专业做酒店网站对于 MySQL 数据库来说#xff0c;好的逻辑表和物理表的规划至关重要#xff0c;我们需要根据查询语句来针对性地设计 Schema #xff0c;没有万能好用的 Schema。一个 denormalized 的 schema 可以在某些场景下加速语句查询#xff0c;但是放在其他应用场景下就会适得其反…对于 MySQL 数据库来说好的逻辑表和物理表的规划至关重要我们需要根据查询语句来针对性地设计 Schema 没有万能好用的 Schema。一个 denormalized 的 schema 可以在某些场景下加速语句查询但是放在其他应用场景下就会适得其反。增加辅助表可以优化查询但是表的维护成本就很高。MySQL 的实现原理决定了这一事实。《最全的MySQL性能指南》系列文章重点讨论数据库索引和 MySQL 的 schema 设计。在读之前读者应该熟悉数据库设计基本知识。在系列文章中我们会讲到逻辑设计物理级别的设计和语句执行。MySQL 支持多种数据类型存储数据类型的选择对性能至关重要下面的一些基本原则可以帮助你在不同场景下选择合适的数据类型字段越小越好一般情况下选择可以存储你的数据的最小数据类型越小越快因为占用更少的磁盘空间更少的内存和 CPU 缓存。小的数据类型也只需要较少的 CPU 周期来处理。简单即更优处理简单的数据类型通常耗费更少的 CPU 周期。举个例子整数比较比字母比较更快将字母用数字表示更好。而且我们不应该用字符串而是应该用 MySQL 原生的日期和时间类型来存储时间数据用整数来存储 IP 地址。尽可能避免 NULL很多表都支持带 null 值的字段即便是应用软件没有 null 这么个概念也还是会在表里加入这个一个值做为默认值。最好的方式是每一个字段都标注 NOT NULL除非应用确实有 NULL 的概念。MySQL 对涉及 null 字段的查询无法做到最佳优化因为 null 值本身让索引和数值比较更加复杂。带 null 值的字段消耗更多的存储空间而且需要一些特殊的处理。当带 null 值的字段被加了索引的时候每一个字段值都会多出一个字节在 MyISAM 存储引擎中还有可能将固定大小的索引变成随机大小的索引。把一个带 null 的字段修改成 NOT NULL 的字段带来的性能提升不大所以如果不是必须的话请不要在建表之后去修改但是如果要在字段上加索隐最好还是用 NOT NULL。也有例外的情况。比如 InnoDB 用一个比特来存储 NULL所以对于稀疏表是很节省空间的。但是 MyISAM 就不是这样。确定字段类型的第一步就是了解数据的基本特征数值型字符串型时间型等等。这个很好确定但是也有上文提到的特殊情况。下一步就是确定具体的数据类型。很多 MySQL 的数据类型可以存储相同的数据但是对数据的范围要求、精度、存储格式却不一样。某些数据格式有特殊的性质。比如说DATETIME 和 TIMESTAMP 字段可以存储相同的数据 - 日期和时间精确到秒。但是 TIMESTAMP 只需要 DATETIME 一般的存储空间能够存储时区信息并且还支持自动数据生成。但是TIMESTAMP 能表示的时间范围就小很多而且其自动数值生成功能有时候会产生不要的效果整数数字有两种类型整数和实数(带小数点位的数字)。如果是存储整数我们可以可以使用TINYINT (8 bits能存储 到 范围的整数)SMALLINT (16 bits能存储 到 范围的整数)MEDIUMINT (24 bits能存储 到 范围的整数)INT (32 bits能存储 到 范围的整数)BITINT (64 bits能存储 到 范围的整数)整数类型的可以自带 UNSIGNED 属性该属性去除了所有负值将能表示的最大值翻两倍。例如TINYINT UNSIGNED 可以存储 0 到 255 的数值而 TINYINT 只能存储 -128 到 127。Signed 和 unsigned 数据类型占用相同的存储空间性能效果相同所以根据你自己的需求随意设置就好。我们对数据类型的选择决定了 MySQL 存储数据的方式。但是整数相关的计算通常用的是 64位 BITINT 的方式进行就算在32位处理器中也是如此。MySQL 可以指定整数的上限位数比如 INT(11)这其实是一个没啥卵用的功能这并不会改变整数的范围仅仅只是制定 MySQL 在 command line 下显示整数所用的占位符的个数。从存储和计算角度上来说INT(1) 和 INT(20) 是一样的实数实数是带有小数点位的数字但它们不仅仅存储分数性质的数字你也可以用 DECIMAL 来存储达到连 BIGINT 都存不下的数值。MySQL 支持完全准确和近似值类型的实数FLOAT 和 DOUBLE 支持用浮点方式的近似计算计算方式因处理器的不同而稍有差异。DECIMAL 是用来存储完全准确的实数的。在 MySQL 5.0 以及以后的版本中DECIMAL 支持完全精确计算。而 MySQL 4.1 和更早的版本则是使用浮点方式来进行 DECIMAL 的运算这在某些情况下会出现很诡异的计算结果所以在老版本中DECIMAL 只是一个 “存储类型”。在 MySQL 5.0 以及以后的版本中MySQL server 负责 DECIMAL 的所有计算因为 CPU 本身不支持 DECIMAL 运算。浮点运算(Floating-point )会快很多因为 CPU 支持浮点运算。浮点(floating-point)和 DECIMAL 类型都支持指定精度。对于 DECIMAL 字段可以指定小数点之前和之后的最大位数注意这会影响字段的存储。MySQL 5.0 以及以后的版本中的 DECIMAL 支持最高带有 65 个数字的数值。相比于 DECIMAL 浮点类型通常要求较少的存储空间来存储相同的数据。一个 FLOAT 字段占用 4 个字节DOUBLE 占用 8 个字节并且精度更高。和整数一样浮点和 DECIMAL 只是存储方式上的区别计算都是通过 DOUBLE 的计算方式进行的。因为占用更多的存储空间和计算资源应该只有在需要精确小数计算的时候你才应该使用 DECIMAL。一个可用的场景是存储金融相关的数据。但是对于大体量数据更好的方法是用 BIGINT将货币数据转化成可复原的整数形式。比如你需要存储小数点后两位的货币数据你可以将原数值乘以一百万存成 BITINT这样可以防止因为浮点数据存储和 DECIMAL 运算带来的精度误差。字符串类型MySQL 支持相当多的字符串类型这些类型在 4.1 版本和 5.0 版本中有了很大的变化也因此变得更加复杂。MySQL 4.1 开始每个字符串字段能有不同的字符集和对应的字符集排序规则。VARCHAR 和 CHAR 类型两个主要的字符串类型是 VARCHAR 和 CHAR每个存储引擎对这两者的存储方式都很不一样。我们这里仅讨论 InnoDB 和 MyISAM 两种存储如果你关注的是其它存储引擎请参阅对应的文档。我们来看一下 VARCHAR 和 CHAR 是如何在磁盘上存储的。存储引擎在内存和磁盘上存储 VARCHAR 和 CHAR 的方式可能不一样不仅如此当 MySQL 把字符串从存储引擎中读出来的时候还会进行二次转化。以下是两种类型的一般比较VARCHARVARCHAR 存储的是变量长度的字符串也是最常见的数据类型。VARCHAR 比定长的字符串可以占用更少的存储空间因为 VARCHAR 存储短的字符串就只需要更少的空间。但是在 MyISAM 中用 ROW_FORMATFIXED 创建出来的表用的就是占用固定的磁盘空间这可能会带来存储资源的浪费。VARCHAR 借助 1 或者 2 个额外的字节来记录字符串的长度。如果字段的最大长度小于等于 255 个字节就用一个字节如果大于 255 就用 两个字节。在拉丁语字符集情况下VARCHAR(10) 最高占用 11 个字节的存储空间VARCHAR(1000) 占用 1002 个字节因为额外需要两个字节来存储。VARCHAR 对性能提升有帮助因为占用更少的空间。但是因为是长度可变的这可能会带来额外的开销。如果长度超过的了最大值不同的存储引擎会有不同的策略。例如MyISAM 会将一行数据切分而 InnoDB 可能会将表分成多个 page其他引擎可能根本就不会在原数据上做修改。当最长字符串长度远大于平均字符串长度字符串更新很少见(因为上文提到的切分就不会出现)并且使用 UTF-8 这样的复杂字符集(每一个字都占用不同字节数量的存储空间)的时候VARCHAR 是一个不错的选择。MySQL 5.0 以及以后的版本中会保留字符串后面的空格而在 4.1 以及以前的版本中MySQL 会将尾部空格剔除。CHARCHAR 是定长的MySQL 总是按照一定数量划分出足够的空间存储 CHAR 的时候MySQL 总是删除尾随空格。CHAR 在相互比较的时候为了长度相同会在尾部添加空位。如果存储很短的字符串或者所有字符串都基本一样长CHAR 是一个更好的选择。比如说CHAR 特别适合存储密码的 MD5 值MD5 值的长度都是相同固定的。对于经常变化的数据CHAR 也是一个比 VARCHAR 更好的选择因为定长字符串不会出现分片现象。对于很短的字符串字段CHAR 有更好的性能CHAR(1) 用来存储 Y 和 N 在单字节字符集中只需要一个字节而 VARCHAR(1) 则需要两个字节其中一个用来记录长度。CHAR 和 VARCHAR 的姊妹类型是 BINARY 和 VARBINARY用来存储二进制字符串。二进制字符串和普通字符串类似只是存的是字节不是字母。在尾部添加空位也不一样MySQL 给 BINARY 尾部添位用的是 \0 而不是空格而且不会剔除尾部 \0当数据是二进制的而且需要比较的情况下BINARY 和 VARBINARY 是比较好的选择。二进制比较的优点除了不区分大小写MySQL 是一个一个字节地比较 BINARY 字符串比较每个字节的数值这样做的结果就是二进制比较会更加简单快速。一般化的处理方式可能会适得其反存储 “hello” 这个单词对于 VARCHAR(5) 和 VARCHAR(200) 需要的存储空间是一样的那用 VARCHAR(5) 好在哪里呢确实会好很多VARCHAR(200) 会消耗更多的内存因为 MySQL 会分配固定的内存空间这对排序和内存操作带来很大压力。BLOB 和 TEXT 类型BLOB 和 TEXT 是用来存储占体很大的数据分别以二进制和字符的形式存储。实际上不止是 BLOB 和 TEXT 这两个还有 TINYTEXTSMALL TEXTTEXTMEDIUMTEXT和 LONGTEXTTINYBLOBSMALLBLOBBLOBMEDIUMBLOB和 LONGBLOB。 BLOB 等同于 SMALLBLOB TEXT 等同于 SMALLTEXT。和其它数据类型不同的是MySQL 存储 BLOB 和 TEXT的方式有些特殊InnoDB 会用一个单独的“外部”存储区域表里实际存的是这个外部区域的位置信息(1 到 4 个字节)。BLOB 和 TEXT 的唯一区别是 BLOB 类型存储的是二进制数据没有 collation 和字符集而 TEXT 则有字符集和 collation。MySQL 用了和其它类型不同的方法给 BLOB and TEXT 排序不会给整个字符串排序而是给前 max_sort_length 数量的字节排序。如果你只想根据前面几个字符排序要么降低 max_sort_length 要么使用 ORDER BY SUBSTRING(column, length)MySQL 无法按照这些数据类型的原长建立索引也不能在排序的时候用到索引。BLOB 和 TEXT 类型 - 磁盘临时表 排序因为内存存储引擎(memory storage engine)不支持 BLOB 和 TEXT 类型查询 BLOB 和 TEXT 字段并且需要创建临时表的话的查询语句需要使用 MyISAM 的磁盘临时表(Percona 的内存存储引擎也支持)即使是访问小部分数据也是如此。这会对性能带来很严重的影响即便你将 MySQL 的配置设置成在内存存放临时表也会导致很多的大开销的系统调用。最好的方法是不到万不得已的情况下不要使用 BLOB 和 TEXT 类型。如果一定需要的话就在需要使用 BLOB 字段的语句(包括 ORDER BY 语句)中使用 SUBSTRING(column, length)将其转换成字符形式因为这样就可以使用内存临时表了。这里要确保使用比较短的 substring保证临时表不会比 max_heap_table_size 或者 tmp_table_size 更大否则 MySQL 会将表变成磁盘形式的 MyISAM 表。该方法同样适用于排序。举个例子假设有一个一千万行的表占用了几个G的磁盘空间表中包含一个 VARCHAR(1000)utf8字符集的字段每个字母最多占用 3 个字节所以最长的字符串值有 3000 个字节。如果在 ORDER BY 语句中涉及该字段那么整个表的查询会产生 30 多个 GB 的临时表用来排序如果 EXPLAIN 中的 “Extra” 字段包含 “Using temporary”那么代表着查询语句用到了临时表。ENUM有些时候可以用 ENUM 替代字符串类型ENUM 字段存储某些预设好的字符串值。MySQL 用非常节省空间的方式存储 ENUM根据预设值的个数只用一个或者两个字节存储存储方式是用一个整数当作字段值这个整数等于所有预设值列表里某个具体字符串的下表通过一个查找表来维护这个映射。举个例子mysql CREATE TABLE enum_test(- e ENUM(fish, apple, dog) NOT NULL- );mysql INSERT INTO enum_test(e) VALUES(fish), (dog), (apple);三行数据实际上存储的是数字不是字符串mysql SELECT e 0 FROM enum_test;-------| e 0 |-------| 1 || 3 || 2 |-------如果 ENUM 的真实值是数字那么这会导致很大的歧义所以Jack建议不要这么做。另外ENUM 是根据对应的整数值排序的不是按照真实数据mysql SELECT e FROM enum_test ORDER BY e;-------| e |-------| fish || apple || dog |-------解决办法是可以在定义 ENUM 成员值的时候有意按照顺序指定真实值你也可以使用 FIELD() 来明确指出一个查询语句的相关顺序但是这样 MySQL 就无法在排序的时候使用索引了mysql SELECT e FROM enum_test ORDER BY FIELD(e, apple, dog, fish);-------| e |-------| apple || dog || fish |-------像上面这种情况如果我们定义 ENUM 值的时候就按照字母排好序我们之后就不需要用 FIELD() 了。ENUM 一个最大的缺点就是预设值不能随意再添加如果要添加或者删除需要用到 ALTER TABLE所以如果预设值在将来可能会变动ENUM 可能不是一个最佳选择除非 ALTER TABLE 不会对应用产生大的影响这在 MySQL 5.1 有比较好的支持。因为 MySQL 存储的是整数而且需要将整数映射到具体的预设值ENUM 字段会有一些额外的开销。这可以通过 ENUM 的小范围预设值来抵消但不是所有情况都是如此比如说把 CHAR 或者 VARCHAR 字段和一个 ENUM 字段 join 起来会比和另一个 CHAR 或者 VARCHAR 字段 join 起来要慢。为了展示说明这里通过一个举例来简单看一下 MySQL 执行 join 的速度。我们有一个 primary key 比较“宽”的表CREATE TABLE webservicecalls (day date NOT NULL,account smallint NOT NULL,service varchar(10) NOT NULL,method varchar(50) NOT NULL,calls int NOT NULL,items int NOT NULL,time float NOT NULL,cost decimal(9,5) NOT NULL,updated datetime,PRIMARY KEY (day, account, service, method)) ENGINEInnoDB;这个表有大概11万行数据大小只有 10 MB所以整个表可以放入内存。service 字段包含 5 个预设值平均长度是 4 个字符method 字段包含 71 个预设值平均长度是 20 个字符。我们复制了一份这个表并且将 service 和 method 字段转成了 ENUMCREATE TABLE webservicecalls_enum (... 省略 ...service ENUM(...预设值省略...) NOT NULL,method ENUM(...预设值省略...) NOT NULL,... 省略 ...) ENGINEInnoDB;然后我们测量了一下根据 primary key 来 join 表的性能mysql SELECT SQL_NO_CACHE COUNT(*)- FROM webservicecalls- JOIN webservicecalls USING(day, account, service, method);我们将上述查询语句稍作修改来相互 join VARCHAR 和 ENUM 字段一下是测量结果VARCHAR join VARCHAR2.6 秒VARCHAR join ENUM 1.7 秒ENUM join VARCHAR 1.8 秒ENUM join ENUM 3.5 秒将被 join 的字段改成 ENUM 之后速度提升但是 ENUM join VARCHAR 慢了一些所以我们发现如果 VARCHAR 字段不是被 join 的情况可以使用 ENUM。通常情况下用 ENUM 这样的整数对照表比 join 字符要来的高效。然而还有一个将 service 和 method 字段转成 ENUM 的好处根据 SHOW TABLE STATUS 中的 Data_length 字段转换之后的表缩小了三分之一。在某些时候存储方面带来的提升可能大过 ENUM join VARCHAR 带来的性能耗损。而且primary key 也小了一半。在 InnoDB 引擎中缩小 primary key 也能让索引大大缩小Date 和 Time 类型MySQL 针对日期和时间有多种不同的类型。比如 YEAR 和 DATE。MySQL 能存储的最小时间单位是秒(MariaDB 是微秒)但却能在微秒级别上进行计算。大多数时间相关的数据类型没有替代类型所以也就不存在哪个更好的说法。唯一的问题就是如果需要同时存储日期和时间该怎么办。对此 MySQL 提供两个类似的数据类型DATETIME 和 TIMESTAMP。对于大多数应用来说两者都可以但某些情况下就有优劣之分了我们具体来看一下DATETIME这个类型可以存储大范围的数据从 1001 年到 9999 年精度到达秒级存储日期和时间用一个整数形式表示YYYYMMDDHHMMSS无时区使用 8 个字节的存储空间。默认情况下MySQL 显示 DATETIME 的格式是 “2008-01-16 22:37:08”这是 ANSI 标准下规范的日期时间表示方法TIMESTAMP顾名思义TIMESTAMP 存储的是从 格林尼治时间(GMT)1970 年 1 月 1 日凌晨过去了多少秒和 Unix 时间戳是一样的。TIMESTAMP 只需要 4 个字节存储所以可能表示的时间范围比 DATETIME 小很多从 1970 年到 2039 年。MySQL 提供 FROM_UNIXTIME() 和 UNIX_TIMESTAMP() 进行 Unix 时间和日期之间的转换。MySQL 4.1 和之后的版本用和展示 DATETIME 相同的方式展示 TIMESTAMP 的值但是 MySQL 4.0 和之前的版本在展示的时候没有标点符号但这仅仅只是展示形式的不同TIMESTAMP 的存储格式在所有 MySQL 的版本中都是一样的TIMESTAMP 的展示数值也取决于时区MySQL操作系统和访问客户端都有自己的时区设置。所以当 TIMESTAMP 存储的是 0 的时候展示出来的是 1969-12-31 19:00:00 EST和 GMT 有 5 个小时的时差。这个区别需要注意如果是在不同时区存储和访问时间数据TIMESTAMP 和 DATETIME 的应对方式是不同的。前者是带了时区后者强调日期和时间的展示形式。TIMESTAMP 也有 DATETIME 不具备的特殊性质。默认情况下如果没有制定具体的值MySQL 会把第一个 TIMESTAMP 字段的值设成当前时间一般情况下如果可以用 TIMESTAMP 尽量用因为 TIMESTAMP 比 DATETIME 更节省存储空间。一些人会将 UNIX 时间戳存成整数形式但是这样并没有什么优势整数形式比较不和规范所Jack我建议不要这么做。那如果需要存储秒级一下的数据呢比如毫秒。MySQL 目前没有特定的数据格式支持但是你可以用现有的类型做一些设计你可以用 BIGINT 存储微秒级的时间戳或者你可以用 DOUBLE 来存储带小数点的秒级数据。哪种方法都合适或者可以直接用 MariaDBBit-存储数据类型MySQL 里面的少数存储类型支持用数据中的某些 bit 用压缩的方式存储数据。所有这些格式是用字符串形式存储BIT在 MySQL 5.0 之前BIT 就是 TINYINT在是在 MySQL 5.0 和以后的版本中就是一个完全不同的数据类型你能用 BIT 字段存储一个或者多个 true/false 值BIT(1) 定义了一个包含了单个 bit 的值BIT(2) 包含两个 bit以此类推BIT 字段的最大程度是 64 个 bits。BIT 的性质在不同存储引擎中是不一样的。MyISAM 将所有 bit 字段放在一起所以 17 个 BIT 字段只需要 17 个 bit 就行(字段值不能出现 NULL), MyISAM 将其转换成 3 个字节存储。其他存储引擎中例如内存的 InnoDB将 bit 用最小整数表示这样会比较消耗存储空间。MySQL 将 BIT 当作字符串对待而不是数值。当你读取一个 BIT(1) 字段的时候显示出来的实际上是一个字符串值是 0 或者 1而不是 ASCII ”0“ 或者 ”1“。但是如果用数值的方法读取那结果就是数值。例如如果存储的是 b00111001 (相当于数字 57)将其存储在 BIT(8) 字段中读取之后你会得到字母编码是 57 的字符串这也是 ”9“ 的ASCII 字符码mysql CREATE TABLE bittest(a bit(8));mysql INSERT INTO bittest VALUES(b00111001);mysql SELECT a, a 0 FROM bittest;-------------| a | a 0 |-------------| 9 | 57 |-------------这会产生很多歧义Jack建议慎用 BIT在大多数场景下最好不要使用 BIT 类型如果你需要将 true/false 值存在一个单个 bit 的字段中另一个方法就是用 nullable 的 CHAR(0) 字段该字段可以存储无数据(NULL)和长度是0的数据(空字符串)SET如果你需要存储多个 true/false 值可以考虑用 MySQL 自带的 SET 数据类型将其合并成一个字段MySQL 对此的存储方式是用一个 bit set。存储起来非常高效MySQL 还可以利用 FIND_IN_SET() 和 FIELD() 优化查询语句。最大的缺点就是如果需要修改字段的定义那么代价就很高需要 ALTER TABLE 语句这在大的表中代价是很大的而且你不能在 SET 字段上用索引整数字段上的位运算另外一种和 SET 有相同效果的方案是始终整数表示一个 bit 集合例如你可以将 8 个 bits 放入一个 TINYINT用位运算符来处理它们。在应用中还可以利用代名称的常数来表示每一个 bit简化复杂度。这种方法的优点在于我们可以不需要 ALTER TABLE 就能改变字段含义。缺点是你的查询语句会变的比较复杂和难懂有些人喜欢位运算觉得逼格高但是有些人则不喜欢所以这主要还是看个人和团队喜好。一个合并 bits 的应用就是 ACL控制访问权限。每个 bit 或者 SET 元素代表了一个访问权限开关比如 CAN_READCAN_READCAN_DELETE。如果你使用的是 SET 字段类型那么你会依赖 MySQL 的 bit 映射表如果使用整数字段映射表会放在应用当时。一个 SET 字段查询语句举例mysql CREATE TABLE acl (- perms SET(CAN_READ, CAN_WRITE, CAN_DELETE) NOT NULL- );mysql INSERT INTO acl(perms) VALUES (CAN_READ,CAN_DELETE);mysql SELECT perms FROM acl WHERE FIND_IN_SET(AN_READ, perms);---------------------| perms |---------------------| CAN_READ,CAN_DELETE |---------------------如果你用的是一个整数那么上述举例就是mysql SET CAN_READ : 1 0,- CAN_WRITE : 1 1,- CAN_DELETE : 1 2;mysql CREATE TABLE acl (- perms TINYINT UNSIGNED NOT NULL DEFAULT 0- );mysql INSERT INTO acl(perms) VALUES(CAN_READ CAN_DELETE);mysql SELECT perms FROM acl WHERE perms CAN_READ;-------| perms |-------| 5 |-------我们这里使用的变量来定义但你也可以在应用中使用自己的常数。ID 字段的类型选择给 ID 类型的字段选择一个合适的字段类型至关重要。这些字段经常会被拿去和其它字段比较(比如 join)或者用这点字段去查找其它字段。你也会用它当多 foreign keys所以如果是给这些字段选择类型还需要考虑其他相关表的相关字段类型。在选择类型的时候你不仅要考虑存储方面的问题还需要结合 MySQL 是如何对这个类型进行计算和比较的。比如MySQL 存储 ENUM 和 SET 类型的方式是用整数在比较字符串的时候会将其转换成字符串。当选定了一个 ID 字段的类型之后在其它表的相关字段中也需要使用相同的类型需要完全相同比如是否都是 UNSIGNED选择占用空间最小的类型来存储适当留出额外空间来应对将来的增长需求。比如如果你要 province_id 字段存储国内所有的省份你不需要存储几百万个数值所以不要用 INTTINYINT 就足够了而且还省了 3 个字节的存储空间如果你将这个字段当作 oreign key 和其它表相连3 个字节能带来巨大的性能差异。这里Jack给几点建议整数类型整数类型是 ID 类型的最佳选择因为处理起来很快并且可以使用 AUTO_INCREMENTENUM 和 SETENUM 和 SET 非常不适合用作 ID 类型的字段只是在小的静态定义类型的表中可以用作 ID 类型的字段。ENUM 和 SET 字段适合存储比如订单状态产品类型或者性别等数据。举个例子如果你用 ENUM 定义产品类型那么你需要另一个 ID 是 ENUM 字段的表但这样的情况应该避免。字符串类型尽量避免使用字符串类型的 ID 字段因为占用太多的空间而且比整数型要慢很多。而且要慎用如果需要存储 UUID 数据你应该将 UUID 中的中划线剔除或者用 UNHEX() 将其转换成 16 字节的数字然后存储在 BINARY(16) 的字段中之后你就能用 HEX() 将它们读成16进制的数字。特殊类型的数据某些数据没有直接对应的存储类型毫秒级别的时间戳就是一个例子。我们在上文当中已经阐述了如何存储这类型的数据。另一个例子就是 IPv4 地址。人们通常使用 VARCHAR(15) 来存储但是IPv4 实际上是 unsigned 的 32 位整数不是字符串。里面的点符号只是为了方便大家阅读罢了。我们应该将 IP 地址存成 unsigned 整数。MySQL 支持用 INET_ATON() 和 INET_NTOA() 将两者相互转换。总结费脑码字不易如若有用还请点赞分享更赞参考^某些第三方存储引擎例如 Infobright在存储格式和压缩方式上和大多数 MySQL 原生支持的存储引擎很不一样^读取 BINARY 的时候要格外注意MySQL 会在尾部添加 \0所以如果要比较 BINARY一定要记住这一点^在不同 MySQL 版本之间TIMESTAMP 有不同的复杂规则所以你需要亲自验证^如果你使用 InnoDB如果字段类型不完全一样是不能创建 foreign key 的
http://www.pierceye.com/news/704835/

相关文章:

  • 企业网站优化方式wordpress 外链播放器
  • 设计衣服的网站久久诗歌网
  • 上海网站营销it运维网
  • 一起做网店广州站怎么推广软件让别人下载
  • 王晴儿网站建设方案wordpress媒体库 ftp
  • 乡村建设网站自己的网站做防伪码
  • 企业网站托管新乡企业网站建设
  • 移动网站开发课程设计莱芜四中网站
  • 做论坛网站赚钱吗做电影网站要几G空间的
  • 网站建设综合实训心得intitle 网站建设
  • 天津市做网站公司wordpress demo
  • 做外贸网站公司公司网站的seo优化
  • 网站页面设置上海微信小程序开发公司
  • 中企动力是怎么建设网站的房地产市场低迷
  • 成都眉山网站建设平台兼职网站开发
  • 化妆品网站的建设 论文php技术的网站开发
  • 女人与黑狗做视频网站网站seo关键词排名
  • ps制作个人网站营销软文怎么写
  • 建立网站的方案南京小程序开发网站建设
  • 类似淘宝的网站怎么做的产品推广会议流程
  • 写作网站的文风软件开发的基本过程
  • 做胃镜多少钱那好天津津门网站a顺德高端网站
  • 网站升级维护中 模板用ps怎么做网站背景
  • 免费商城网站建设建设银行企业网站首页
  • 北京哪家网站建设公司比较好帝国cms怎么做网站地图
  • 做网站制作外包数据可视化
  • 专注大连网站建设青海项目信息网
  • 网站开发开题报告范文可以做免费的网站吗
  • 淄博网站备案wordpress代码实现下载
  • 网站做全景做的好看的网站