实现 MySQL 对象层的更好方法

发布于 2024-12-01 08:30:35 字数 1004 浏览 2 评论 0原文

我不是 MySQL 专业人士,但想做一些类似于关系 MySQL 表之上的对象层之类的事情。

我想要有很多“结构”,其类型为“bigint”、“longtext”、“datetime”、“double”的字段存储在 7 个表中。

entity_types (et_id, et_name) - “结构”列表;

entity_types_fields(etf_id、parent_et_id、.....、etf_ident、etf_type) - 存储在一张表中的所有结构的结构属性列表; etf_​​type 包含引用下面描述的 4 个表之一的 int 值 (0,1,2,3)。

实体(e_id、et_id) - 所有可用实体的列表(实体的 ID 和类型 ID)

和 4 个数据表(包含实体的所有数据) -

entities_props_bigint (parent_e_id、parent_etf_id、ep_data) - 对于 BIGINT 数据属性 entities_props_longtext (parent_e_id、parent_etf_id、ep_data) - 用于 LONGTEXT 数据属性 entities_props_datetime (parent_e_id、parent_etf_id、ep_data) - 用于 DATETIME 数据属性 entities_props_double (parent_e_id, Parent_etf_id, ep_data) - 对于 DOUBLE 数据属性

从此类数据层进行选择的最佳方法是什么?

让我有 e_id (实体的 ID)列表,每个实体可以有任何类型。我想获取预定义的属性列表。如果某些实体没有这样的属性,我希望它等于 NULL。

您有一些有关如何操作的信息吗?可能您有一些链接或已经处理过此类事情。

谢谢!

I am not a pro in MySQL, but want to do something like Object Layer above relational MySQL tables.

I want to have very many "structures" with a fields of type "bigint", "longtext", "datetime", "double" stored in just 7 tables.

entity_types (et_id, et_name) - list of "structures";

entity_types_fields (etf_id, parent_et_id, ....., etf_ident, etf_type) - list of structure properties stored in one table for ALL structures; etf_type contains int value (0,1,2,3) which referenced to one of 4 tables described below.

entities (e_id, et_id) - list of all available entities (id and type id of entity)

and 4 data tables (containing all data for entities) -

entities_props_bigint (parent_e_id, parent_etf_id, ep_data) - for BIGINT data properties
entities_props_longtext (parent_e_id, parent_etf_id, ep_data) - for LONGTEXT data properties
entities_props_datetime (parent_e_id, parent_etf_id, ep_data) - for DATETIME data properties
entities_props_double (parent_e_id, parent_etf_id, ep_data) - for DOUBLE data properties

What the best way to do selection from such data layer ?

Let I have list of e_id (id of entities), each entity can have any type. I want to get predefined list of properties. If some of entities don't have such property, I want to have it equal to NULL.

Do you have some info about how to do it ? May be you have some links or have already deal with such things.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

紧拥背影 2024-12-08 08:30:35

通过在关系数据库之上实现整个元数据系统,您正在重新发明轮子 。许多开发者已经尝试过做你正在做的事情然后用SQL来查询它,就好像它是关系数据一样。但在 SQL 中实现非关系数据和元数据系统比您预期的要困难。

我已将您问题的 relational 标记更改为 eav,因为您的设计是 实体属性值设计。 Stack Overflow 中的标签数量限制为 5 个。但你应该意识到你的设计不是相关的。

关系设计必然对实体的所有实例具有一组固定的属性。在关系数据库中表示这一点的正确方法是使用表的列。这允许您为每个属性指定名称数据类型,并确保同一组名称及其数据类型适用于表的每一行。

从此类数据层中进行选择的最佳方法是什么?

查询设计的唯一可扩展方法是将属性数据和元数据作为行获取,并在应用程序代码中重建对象。

SELECT e.e_id, f.etf_ident, f.etf_type, 
    p0.ep_data AS data0, 
    p1.ep_data AS data1, 
    p2.ep_data AS data2,
    p3.ep_data AS data3
FROM entities AS e
INNER JOIN entity_type_fields AS f ON e.et_id = f.parent_et_id
LEFT OUTER JOIN entities_props_bigint   AS p0 ON (p0.parent_e_id,p0.parent_etf_id) = (e.e_id,f.etf_id) 
LEFT OUTER JOIN entities_props_longtext AS p1 ON (p1.parent_e_id,p1.parent_etf_id) = (e.e_id,f.etf_id) 
LEFT OUTER JOIN entities_props_datetime AS p2 ON (p2.parent_e_id,p2.parent_etf_id) = (e.e_id,f.etf_id) 
LEFT OUTER JOIN entities_props_double   AS p3 ON (p3.parent_e_id,p3.parent_etf_id) = (e.e_id,f.etf_id) 

在上面的查询中,每个实体字段最多匹配一个属性,其他数据列将为空。如果所有四个数据列都为空,则实体字段丢失。


回复你的评论,好吧,现在我更好地理解你想要做什么。您在树中有实体实例的集合,但每个实例可能是不同的类型。

我的设计方式如下:

  • 将所有实体子类型共有的所有属性存储在一种超类型表中。

实体(e_id、entity_type、name、date_created、creator、sku 等)

  • 将特定于实体子类型的任何属性存储在自己的表中,如 Martin Fowler 的 类表继承设计。

entity_books(e_id,isbn,pages,publisher,volumes,etc.)

entity_videos(e_id,format,region,discs,etc.)

entity_socks(e_id,fabric,size,color,etc.)

  • 使用 闭包表设计用于对对象的层次结构进行建模。

entity_paths(ancestor_e_id, Descendant_e_id, path_length)

有关类表继承和闭包表的更多信息,请参阅我的演示文稿 SQL 中实用的面向对象模型SQL 中的分层数据模型,或我的书 SQL 反模式卷 1:避免数据库编程的陷阱,或 Martin Fowler 的书企业应用程序架构模式。

You're reinventing the wheel by implementing a whole metadata system on top of a relational database. Many developers have tried to do what you're doing and then use SQL to query it, as if it is relational data. But implementing a system of non-relational data and metadata in SQL is harder than you expect.

I've changed the relational tag of your question to eav, because your design is a variation of the Entity-Attribute-Value design. There's a limit of five tags in Stack Overflow. But you should be aware that your design is not relational.

A relational design necessarily has a fixed set of attributes for all instances of an entity. The right way to represent this in a relational database is with columns of a table. This allows you to give a name and a data type to each attribute, and to ensure that the same set of names and their data types apply to every row of the table.

What the best way to do selection from such data layer ?

The only scalable way to query your design is to fetch the attribute data and metadata as rows, and reconstruct your object in application code.

SELECT e.e_id, f.etf_ident, f.etf_type, 
    p0.ep_data AS data0, 
    p1.ep_data AS data1, 
    p2.ep_data AS data2,
    p3.ep_data AS data3
FROM entities AS e
INNER JOIN entity_type_fields AS f ON e.et_id = f.parent_et_id
LEFT OUTER JOIN entities_props_bigint   AS p0 ON (p0.parent_e_id,p0.parent_etf_id) = (e.e_id,f.etf_id) 
LEFT OUTER JOIN entities_props_longtext AS p1 ON (p1.parent_e_id,p1.parent_etf_id) = (e.e_id,f.etf_id) 
LEFT OUTER JOIN entities_props_datetime AS p2 ON (p2.parent_e_id,p2.parent_etf_id) = (e.e_id,f.etf_id) 
LEFT OUTER JOIN entities_props_double   AS p3 ON (p3.parent_e_id,p3.parent_etf_id) = (e.e_id,f.etf_id) 

In the query above, each entity field should match at most one property, and the other data columns will be null. If all four data columns are null, then the entity field is missing.


Re your comment, okay now I understand better what you are trying to do. You have a collection of entity instances in a tree, but each instance may be a different type.

Here's how I would design it:

  • Store any attributes that all your entity subtypes have in common in a sort of super-type table.

entities(e_id,entity_type,name,date_created,creator,sku, etc.)

  • Store any attributes specific to an entity sub-type in their own table, as in Martin Fowler's Class Table Inheritance design.

entity_books(e_id,isbn,pages,publisher,volumes, etc.)

entity_videos(e_id,format,region,discs, etc.)

entity_socks(e_id,fabric,size,color, etc.)

entity_paths(ancestor_e_id, descendant_e_id, path_length)

For more information on Class Table Inheritance and Closure Table, see my presentations Practical Object-Oriented Models in SQL and Models for Hierarchical Data in SQL, or my book SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming, or Martin Fowler's book Patterns of Enterprise Application Architecture.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文