首页 > 解决方案 > 数据库上重复相同的最佳实践

问题描述

我正在开发一个新数据库,其中包含 30 多个具有标准值的表,例如,其中一个存储车辆信息,其中一个字段是燃料,这将始终是“汽油”或“柴油”的选项。

这里的问题是这个数据库将有超过 50,000 辆汽车,所以如果其中 50% 是汽油,我将有 25,000 行重复相同的“汽油”值。

考虑到“汽油”有 8 个字节,“柴油”有 6 个字节。如果我将每行的值存储为varchar(8)带有燃料名称的 a,那么总共 50,000 条记录将达到 200KB + 150KB = 350KB。如果我将它存储为 achar(1)并指定“Gasoline”= 1 和“Diesel”= 2,总大小将减少到 50KB。

在这种情况下,最好的做法是什么?

  1. 创建“list_fuel_names”表并创建表之间的关系;
  2. 处理服务器上的值,如if fuel=1 echo "Gasoline" else if fuel=2 echo "Diesel"
  3. 将燃料名称保存在字段中varchar(8)

任何其他选项都可以讨论和赞赏。最好的祝福。

编辑1:我还有一个“Persons”表,其中存储了一个char(1)值,我没有任何“list_gender”表,所以我将在后端代码中对其进行解码。

编辑 2:由于有 30 多个表具有相同的问题,我必须创建 30 多个表才能列出值,这会有效吗?我问是因为最后我可以使用更多空间,如果我在varchar列中写入值。

标签: sqlsql-server

解决方案


这是一个复杂而微妙的问题。归结为“您要优化什么?”。

首先,我不会优化磁盘空间,除非在少数情况下。您输入这个问题所花费的钱比存储 350KB 所花费的钱还多。

你有几个选择。

“将属性存储为字符串”是最简单的,并且非常具有表现力——你可以只问“找到所有柴油车”等。缺点是你需要一种机制来验证这些字符串——它们必须是柴油或汽油,没有错别字。这种逻辑会在您的应用程序中传播,并且更改它(你好,电动汽车!)可能会很麻烦。

“将属性存储为外键关系”避免了拼写错误,通常被认为是最佳实践。你有一个“fuel_types”表,你的“vehicle”表有一个名为fuel_type的列,外键指向fuel_types;数据库确保只接受有效条目。如果您删除一种燃料类型,数据库可以确保您没有孤立的项目。如果您需要围绕燃料类型引入更多逻辑,例如“税带”或“supplied_by”,您可以扩展您的fuel_types 表。缺点是您需要为数据库访问编写更多代码 - 选择所有车辆时需要更多连接。

“将属性存储为枚举”避免了字符串的一些问题 - 枚举确保您只存储有效选项,并且您可以在新的燃料类型可用时扩展枚举。阅读您的架构的人会立即看到只有有限数量的选项。如果您没有预料到有关燃料类型的任何其他逻辑,那么这是一个不错的解决方案。

“将属性存储为魔术字符串”是一个非常糟糕的解决方案 - 您需要维护大量代码,需要确保“D” = 柴油的很多地方,并且阅读您的架构的人不会想法正在发生。


推荐阅读