如何存储有关表的元数据?

时间:2012-08-29 17:39:20

标签: php mysql metadata

我有一张桌子。一个包含25列的大表,每列包含有关特定实体的原子数据。具体而言,实体是待售的房地产(如房间和房屋),因此该表称为属性

每个属性都有一个子类(实际上它被称为"类型",但我们称之为#34;子类"以避免与数据类型混淆),在这个时刻已经建成并出售了#34;或者"正在建设中,但可以投资于"。它还有很多属性,如地址,价格等,其中大部分都是在子类之间共享,但有些则不是。属性具有不同的数据类型,即:

  • 整数
  • 浮点数
  • 短文字
  • 长篇文章
  • 其他表的外键

这些"其他表"用于从主持人可编辑的选项列表中进行选择(如城区列表,建筑公司列表等)。

主持人应该能够创建新属性并对其进行编辑。用户应该能够查看某些属性的详细信息并搜索满足特定条件的属性,然后将其作为表格查看,可以按其中一列进行排序。

根据属性的子类,只有一部分属性属性可供用户查看,也可供主持人进行编辑。此外,根据数据类型,需要使用不同的HTML代码向用户显示这些属性,并为主持人提供编辑控件,以及在编辑后应执行不同的数据验证检查。

字段列表不是动态的 - 列列表不太可能及其显示方式经常更改,主持人无需更改列。

但是,由于25是一个相当大的数字,我想在一个地方组织并保留有关属性表的所有元数据:有关哪些子类是列的信息以及如何显示,编辑和验证数据。能够以一种简单的方式(如数组)从我的代码中访问所有这些元数据会很高兴。我看到三个选项:


1。常量PHP数组

只需创建一个将使用元数据构建数组的PHP文件或函数,然后在需要时包含/调用它。

优点:

  • 简单。
  • 快速。

缺点:

  • 由于过于冗长和丑陋的PHP代码而难以维护。

2。 MySQL数据库

在数据库中创建表 property_meta 并在其中存储元数据。新表将包含属性表中的列名,此列中数据与每个属性子类的相关性,预期数据类型等。然后创建一个函数将查询必要的字段并将结果数据作为数组返回。

优点:

  • 更容易更改元数据。
  • 维护较少的代码。
  • 稍后可以 扩展以允许用户更改列的列表。在属性表中添加或删除列不会有什么问题。虽然在我看来用户能够动态更改数据库架构是一个严重的代码味道。如果我错了,请纠正我。

缺点:

  • 每当更改元数据时,必须相应地更新服务器数据库。但它只会在数据库架构发生变化时发生,所以没有人关心。
  • 较慢 - 以创建阵列为代价,这将增加与服务器通信的成本和从数据库中选择数据的成本。虽然后者很可能被MySQL查询缓存机制否定。

3。将属性及其属性分隔到不同的表中

按照上述解决方案创建元数据表,只将其命名为 property_attribute 。还可以使用属性 property_attribute 的外键创建 property_data 表,并为属性值创建一列。然后,属性表只包含主键和子类,只能使用带有两个连接的查询检索实际属性值。

优点:

  • 最灵活的解决方案。如果更改了属性列表,则数据库架构将保持不变。

缺点:

  • 每个 property_data 行将包含一段未知类型的数据。将它们全部存储为TEXT或BLOB,或者为单独的数据类型创建单独的列。两种解决方案看起来都很难看。
  • 目前还不清楚如何处理属性表中的以前的外键。几乎不可能对每个插入进行自动数据完整性检查(可能使用触发器?我不确定)。
  • 选择数据将变得更加困难。数据将以property_id - property_attribute_id - value三位一体的形式提取,这不是直观的,需要更多努力才能正确输出。
  • 更重要的是,按一个或多个属性进行过滤和排序会让我感受到伤害的世界。
  • 非常非常慢。
  • 感觉就像用直升机过马路一样。

坦率地说,我不喜欢这些解决方案中的任何一种。但在我看来,第二个是最不丑的。你觉得怎么样?

2 个答案:

答案 0 :(得分:2)

我的第一个问题是:您是在寻求帮助来设计正确的数据库模式,还是在询问如何在代码中处理这些属性/子类?

数据库架构

数据库架构并不完全是我的强项,所以我会把它留给可能比我更了解的人。
我可能只是在一个属性表中将每个字段作为自己的列,但因为它很简单并且允许您正确地索引每个字段。正如你所说,新的领域不会经常被添加。

在PHP中处理它

在我看来,将这些字段视为元数据正在接近它是错误的。每个子类都有自己的一组字段,从技术上讲,它们都是不同类型的实体。

为了清楚起见,我保持这个简单,但这里的内容与我要做的事情有关:

  1. 为每种属性类型创建一个POPO(普通的'php对象)。
    这些只是值对象,类似于您在ORM中可以找到的对象。与Doctrine2实体一样,它们不执行任何持久性。

  2. 这里是我简化示例的地方..这绝对不是跟随SRP并且是糟糕的设计imo,但我是为了简洁而这样写的。

    创建一个工厂类,负责从数据库中获取和保存数据,设置相应的POPO并相应地填充数据。

  3. 这就是它的全部内容。这是一个迷你ORM。如果你想要的话,你实际上可以取消#2并使用正确的ORM ......

    它们的关键是为每个属性子类提供单独的对象。这是有利的,因为:

    • 由于每个属性类型都有自己的类,并且有自己的预定义属性集(以及getter / setter),因此您无需担心填充或使用属于其他属性类型的数据。
    • 它提供了明确的区别,您可以使用它来呈现特定于每种属性类型的模板。 (不是说你之前不能这样做......我觉得这种方式更清洁。)
    • 每个属性类型类都可以从基类继承,以容纳属性类型中常见的所有字段。

答案 1 :(得分:1)

我看到了另外一个选项,除了MySQL之外你还可以考虑使用NoSQL,但是你需要仔细考虑你的要求才能做出正确的产品选择

  • 列存储/列族
  • 文件商店
  • 键值
  • ......还有更多

最大的好处之一是灵活的数据模型,但NoSQL和关系数据库让每个人都有自己的优点,缺点和优势,所以在决定使用nosql解决方案之前你必须知道这个产品