首页 > 解决方案 > 指示在数据库表中具有特殊处理的值的最佳方法是什么?

问题描述

设置。

我有一张表,其中存储了游戏的物理项目列表。项目还具有类别的分层列表。示例基表:

项目

id | parent_id | is_category | name    | description  
-- | --------- | ----------- | ------- | -----------  
1  | 0         | 1           | Weapon  | Something intended to cause damage
2  | 1         | 1           | Ranged  | Attack from a distance
3  | 1         | 1           | Melee   | Must be able to reach the target with arm
4  | 2         | 0           | Musket  | Shoots hot lead.
5  | 2         | 0           | Bomb    | Fire damage over area
6  | 0         | 1           | Mount   | Something that carries a load.
7  | 6         | 0           | Horse   | It has no name.
8  | 6         | 0           | Donkey  | Don't assume or you become one.

系统目前运行在 PHP 和 SQLite 上,但数据库后端很灵活,可能使用 MySQL,前端可能最终使用 javascript 或 Object-C/Swift

问题。

在上面的示例中,程序必须对每个顶级类别及其下方的项目进行不同的特殊处理。例如,武器和坐骑由不同的商人出售,武器可以携带,而坐骑则不能。

在代码中标记顶级层以进行特殊处理的最佳方法是什么?

我的想法。

  1. 我可以在名称上使用字符串匹配,并在第一次执行时将 id 存储在内部常量中。我想避免的充其量是一个丑陋的解决方案。
  2. 我可以在安装时将 id 存储在内部常量中。更好,但仍然不是我喜欢的。
  3. 我可以将数组存储在顶级元素的代码中,而不是将它们放在表中。这会产生很多复杂性,例如子级如何指向顶级父级。必须将另一个 id 添加到表中,该表被 10K 行中的 100 行使用。
  4. 我可以在代码中存储一个数组并在安装时启用标识插入以添加共享静态数组标识的顶级元素。可能是我最好的主意,但我真的不喜欢身份插入的想法,它对我来说感觉不到“数据库”。此外,如果出现新的顶级项目怎么办。也许这些类别的 ID 为 100 万?
  5. 我可以添加一个标志列“varchar(1) top_category”或“int top_category”,其中包含一个指示值的字符或位图。再次在 10k 行中的 10 行上使用一列。

作为一个软件人,我倾向于完善软件解决方案,所以我很好奇他们是否是一个更 DB 类型的解决方案。

标签: database

解决方案


原始表,与操作连接

是的,您可以将所有内容放在一个表中。您只需要为每个场景建立唯一的行。这个sqlfiddle给你一个例子......但是IMO它开始变得难以理解。由于无法进行完全连接,这并不能解决所有情况(这只是 sqlfiddle 的一个限制,否则就很棒。)

IMO,将事情分解成表格更有意义。这是我将如何开始为您描述的某些场景进行模式设计的另一个示例。

基表本身看起来很笨重,但它为数据的使用方式提供了更多的灵活性。

tl;博士前面的类比

数据集不是按行组织的服装列表。这是您存放组成服装的衣服的地方。

因此,将事物拆分为单独的表的笨拙感觉实际上是关系数据库的好处。将所有内容放在一个表中一开始感觉高效且优化......但随着您扩展复杂性......它开始变得痛苦。

把你的模式想象成一个梳妆台。抽屉就是你的桌子。如果你只有几只袜子和内衣,把它们都放在一个抽屉里是有效的。但是一旦你有足够的袜子,把它们和内衣放在同一个抽屉里可能会很痛苦。你有礼服袜,船员袜,踝袜,毛茸茸的袜子。所以你把它们放在另一个抽屉里。一旦你有了衬衫、短裤、裤子,你也开始把它们放在抽屉里。

将所有数据放入单个表的驱动力通常取决于您打算如何使用数据。

假设您的梳妆台储备充足且井井有条,那么您就有几套潜在的独特服装;都整齐地放在你的梳妆台里。你只需要把它们放在一起。选择并加入您是否会组装这些服装。您最喜欢的牛仔裤/T 恤/袜子组合并非全部放在一个抽屉中这一事实并不会使其笨拙或效率低下。它们分开且井井有条的事实使您可以: 1. 快速知道从哪里获得每件物品 2. 查看潜在的其他新的最喜欢的组合 3. 快速查看您的装备的每个组件都有什么

选择先想着装,再想着以后怎么收,这没什么错。如果你只有一套衣服,把所有东西放在一个抽屉里比把每件东西放在一个单独的抽屉里要容易得多。然而,当你扩展你的衣柜时,所有东西的单个抽屉开始变得低效。

您通常希望规划扩展和多功能性。您的程序可以根据需要将数据放在一起。一个组织良好的模式可以为您做到这一点。是否使用 ORM 并进行模型驱动的数据存储;或者从schema开始,然后基于schema构建模型;您的数据需求变得越复杂;两种方法越相似。


推荐阅读