对于一组数据,使用整数优于varchar是否真的值得?

Tre*_*ent 9 sql database optimization

例如,如果我有一个表User,我想存储性别或性别,我会添加一个列sex.

是否真的值得使用整数然后用我最喜欢的编程语言映射它?

喜欢1 => 'Male'2 => 'Female'

有没有表现理由这样做?

或者我可以安全地使用varchar,其中更像 "女性"或"男性",就像我使用mysql一样ENUM

编辑:我在这里和那里它有时更好,有时无关紧要,所以我更多地寻找基准或某种"更好"的答案.

我的意思是我认为使用varchar实际上比整数更有意义,并且只有当性能超过0.3%或者其他时我才会使用整数.

bil*_*nkc 18

如果这是一些自制网站或应用程序,将为10个人服务,那么做任何你想做的事情,性能不会有所作为.

如果这是真实的东西,那么跳过你自己的性别实施并遵循ISO的性标准.或者至少在任何地方都遵守标准(感谢Joe Celko!)

0 = not known
1 = male
2 = female
9 = not applicable
Run Code Online (Sandbox Code Playgroud)

始终对数据类型进行权限调整

  • 磁盘空间节省:
    在我上一份工作中,负责设计表的迂腐人员创建了一个十进制的列,精度为0,因为它应该只有N位数.它与整数数据类型之间的存储成本差异为1或2个字节.但是,由于此表非常大,因此仅在表格上以较小的数据类型计算的总成本节省为千兆字节.

  • 访问节省:大多数人没有考虑的第二个成本是从磁盘读取信息或将数据保存在内存中的成本.在SQL Server中,数据存储在8K页面中.如果您正在使用胖数据类型,则需要更多读取才能从磁盘上获取数据,然后您可以将更少的数据页存储在内存中.从磁盘中提取数据是您获得最大性能成本的地方.如果你想加速使用数据库的东西,不要破坏物理实现.

实现为系统中允许覆盖问题域的最小允许类型.对于像性别这样的东西,在Oracle中使用tinyint(MySQL,SQL Server)或数字(5,0),你将为每个性别花费1个存储空间.

Internationlization

M =男性,F =女性,这似乎很明显.¿真理报?Aqui,nosotroshablamosespañol.这就是我的西班牙语讽刺我,但我的观点是,如果你需要多语言,1将服务于男性,男性,男性,男性,男性等.M或男性只会服务于说英语的观众.更进一步,你会遇到奇怪的表达逻辑"我们需要翻译所有东西,除非它会转向$ culture".将表示逻辑作为UI并将其保留在数据库之外是一种更清晰的设计.

  • i18n的例子,在爱尔兰,女性是Mná,男性是Fir.当写在浴室摊位时,游客非常困惑 (5认同)

dan*_*oel 7

Ortiginal答案:
我建议将其存储在一个CHAR(1)列中,M或者F
它具有足够的表现力以满足特定目的,并具有单个字符比较的速度优势

更新4(固定基准):
所有以前的基准都有一个致命的缺陷,一个(CHAR(1)表)MyISAM和其他所有InnoDB.所以我使用所有表重新创建了数据库,MyISAM现在结果更有意义.

当我使用MySQLWorkbench的向导创建表并忘记更改其他表中的数据库引擎并且默认为InnoDB(我有MySQL 5.5)时出现错误

所以更正的结果如下,(我已经删除了以前的所有基准,因为它们无效):

// select queries
$query['char'] = "select count(*) from test_table where gender = 'M'";
$query['char_lower'] = "select count(*) from test_table where LOWER(gender) = 'm'";
$query['varchar'] = "select count(*) from test_table_2 where gender = 'Male'";
$query['varchar_lower'] = "select count(*) from test_table_2 where LOWER(gender) = 'male'";
$query['tinyint'] = "select count(*) from test_table_3 where gender = 1";

// benchmark result
array
  'char' => float 0.35457420349121
  'char_lower' => float 0.44702696800232
  'varchar' => float 0.50844311714172
  'varchar_lower' => float 0.64412498474121
  'tinyint' => float 0.26296806335449
Run Code Online (Sandbox Code Playgroud)

新结论: TINYINT最快.但是我的建议仍然可以使用CHAR(1),因为未来的开发人员更容易理解数据库.

如果您使用TINYINT,我的建议将是列的名称ismale而不是sex存储0 => Female,1 => male从而使它在原始数据库中更容易理解.

基准的表结构是这样的:

CREATE TABLE `test_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `gender` char(1) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM
Run Code Online (Sandbox Code Playgroud)

在3个表中只有性别列的类型不同,类型是:

CHAR(1), VARCHAR(6), TINYINT
Run Code Online (Sandbox Code Playgroud)

所有3个表都有10000条目.

  • @MartinSmith我已经更新了我的基准测试结果,并带有一个带有"TINYINT"列的表.仍然`CHAR(1)`是赢家.我还在帖子开头总结了我的基准测试结果.看一看.并且结果在多个基准测试运行中是一致的. (2认同)