sql - 数据库上重复相同的最佳实践
问题描述
我正在开发一个新数据库,其中包含 30 多个具有标准值的表,例如,其中一个存储车辆信息,其中一个字段是燃料,这将始终是“汽油”或“柴油”的选项。
这里的问题是这个数据库将有超过 50,000 辆汽车,所以如果其中 50% 是汽油,我将有 25,000 行重复相同的“汽油”值。
考虑到“汽油”有 8 个字节,“柴油”有 6 个字节。如果我将每行的值存储为varchar(8)
带有燃料名称的 a,那么总共 50,000 条记录将达到 200KB + 150KB = 350KB。如果我将它存储为 achar(1)
并指定“Gasoline”= 1 和“Diesel”= 2,总大小将减少到 50KB。
在这种情况下,最好的做法是什么?
- 创建“list_fuel_names”表并创建表之间的关系;
- 处理服务器上的值,如
if fuel=1 echo "Gasoline" else if fuel=2 echo "Diesel"
- 将燃料名称保存在字段中
varchar(8)
任何其他选项都可以讨论和赞赏。最好的祝福。
编辑1:我还有一个“Persons”表,其中存储了一个char(1)
值,我没有任何“list_gender”表,所以我将在后端代码中对其进行解码。
编辑 2:由于有 30 多个表具有相同的问题,我必须创建 30 多个表才能列出值,这会有效吗?我问是因为最后我可以使用更多空间,如果我在varchar
列中写入值。
解决方案
这是一个复杂而微妙的问题。归结为“您要优化什么?”。
首先,我不会优化磁盘空间,除非在极少数情况下。您输入这个问题所花费的钱比存储 350KB 所花费的钱还多。
你有几个选择。
“将属性存储为字符串”是最简单的,并且非常具有表现力——你可以只问“找到所有柴油车”等。缺点是你需要一种机制来验证这些字符串——它们必须是柴油或汽油,没有错别字。这种逻辑会在您的应用程序中传播,并且更改它(你好,电动汽车!)可能会很麻烦。
“将属性存储为外键关系”避免了拼写错误,通常被认为是最佳实践。你有一个“fuel_types”表,你的“vehicle”表有一个名为fuel_type的列,外键指向fuel_types;数据库确保只接受有效条目。如果您删除一种燃料类型,数据库可以确保您没有孤立的项目。如果您需要围绕燃料类型引入更多逻辑,例如“税带”或“supplied_by”,您可以扩展您的fuel_types 表。缺点是您需要为数据库访问编写更多代码 - 选择所有车辆时需要更多连接。
“将属性存储为枚举”避免了字符串的一些问题 - 枚举确保您只存储有效选项,并且您可以在新的燃料类型可用时扩展枚举。阅读您的架构的人会立即看到只有有限数量的选项。如果您没有预料到有关燃料类型的任何其他逻辑,那么这是一个不错的解决方案。
“将属性存储为魔术字符串”是一个非常糟糕的解决方案 - 您需要维护大量代码,需要确保“D” = 柴油的很多地方,并且阅读您的架构的人不会想法正在发生。
推荐阅读
- vue.js - 如何在不绑定到 Vue 实例上的任何内容的情况下将值插入 HTML 属性
- mailchimp - Mailchimp PHP Marketing API 传递请求参数
- flutter - useContext 只能从 HookWidget 的 build 方法中调用
- javascript - 将标题字段添加到 json 对象
- python - 使用openCV python在相同颜色的图像周围绘制轮廓
- reactjs - 用户点击反应后如何重定向到全新的页面?
- java - 使用外部服务或代理记录我的 Java Web 应用程序完成的所有文件访问和处理?
- c++ - 为什么bool函数不返回false?
- assembly - MIPS 运行时错误“无法直接从文本段读取”
- sql - Postgres SQL 查询,返回带有 ID 作为动态键的 JSON 对象