MySQL:如何转换为 EAV - 第 3 部分?
以前的相关文章:
给定一个表:
TABLE: foo
===============================
| id | first_name | last_name |
===============================
| 1 | John | Doe |
| 2 | Jane | Smith |
| 3 | Ronald | McDonald |
-------------------------------
如何做我获取此表并将其转换为这些表(EAV 实现)?:
TABLE: attribute
===========================
| id | fk_id | attribute |
===========================
| 1 | 100 | first_name |
| 2 | 100 | last_name |
---------------------------
TABLE: value
=========================================
| id | attribute_id | row_id | value |
=========================================
| 1 | 1 | 1 | John |
| 2 | 2 | 1 | Doe |
| 3 | 1 | 2 | Jane |
| 4 | 2 | 2 | Smith |
| 5 | 1 | 3 | Ronald |
| 6 | 2 | 3 | McDonald |
-----------------------------------------
注意:
- 将提供 attribute.fk_id。
- value.row_id 用于标识如何将值分组为原始表中的记录。
更新:另外,如何查询 EAV 表,以便使其再次看起来像表 foo
。
Previous Related Posts:
Given a table:
TABLE: foo
===============================
| id | first_name | last_name |
===============================
| 1 | John | Doe |
| 2 | Jane | Smith |
| 3 | Ronald | McDonald |
-------------------------------
How do I take this table and convert it to these tables (an EAV implementation)?:
TABLE: attribute
===========================
| id | fk_id | attribute |
===========================
| 1 | 100 | first_name |
| 2 | 100 | last_name |
---------------------------
TABLE: value
=========================================
| id | attribute_id | row_id | value |
=========================================
| 1 | 1 | 1 | John |
| 2 | 2 | 1 | Doe |
| 3 | 1 | 2 | Jane |
| 4 | 2 | 2 | Smith |
| 5 | 1 | 3 | Ronald |
| 6 | 2 | 3 | McDonald |
-----------------------------------------
NOTES:
- attribute.fk_id will be provided.
- value.row_id is used to identify how the values are grouped as records in the original table.
UPDATE: Also, how do I query the EAV tables so that I can make it look like table foo
again.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我对@Phil 用于填充 EAV 表的解决方案给予+1。一次插入一个属性。
这是反转 EAV 转换的另一种解决方案:
除了使用 EAV 之外,您已将所有值放入 VARCHAR(255) 列或其他列中,因此您丢失了有关原始列各自数据类型的信息。
如果不对属性名称进行硬编码,无论是像 @Phil 所示的连接,还是像我所示的列,实际上没有办法“动态”地做到这一点。这本质上与尝试编写动态数据透视查询相同的问题。
我在演讲中写了更多关于 EAV 的内容 实用面向对象模型在 SQL 和我的书中,SQL 反模式卷 1:避免数据库编程的陷阱。
I give +1 to @Phil's solution for populating the EAV table. Insert one attribute at a time.
Here's another solution to reverse an EAV transformation:
Except that by using EAV, you've put all your values into a column of VARCHAR(255) or whatever, so you have lost information about the respective data types of the original columns.
There's really no way to do it "dynamically" without hard-coding the attribute names, either as joins as @Phil shows, or as columns as I show. It's essentially the same problem as trying to write dynamic pivot queries.
I have written more about EAV in my presentation Practical Object-Oriented Models in SQL and in my book, SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming.
我认为您唯一的希望是使用
foo
表。如果没有 ID,bar
基本上就没用了。尝试这样的事情(假设
attribute.id
是一个自动递增主键)要重建
foo
表,尝试这个呃,谢谢你提醒我为什么我讨厌这种模式
I think your only hope is if you use the
foo
table.bar
is essentially useless without the ID.Try something like this (assuming
attribute.id
is an auto-increment primary key)To reconstruct the
foo
table, try thisErgh, thanks for reminding me why I hate this pattern