MySQL 字段、EAV 等中的多个值
抱歉,标题不能更具有描述性,我仍然不知道我正在处理的内容的名称。
我正在为房地产网站开发一个搜索系统,它运行良好,直到我意识到我忘记考虑我的一些字段(在搜索页面中用作过滤器)可能是多个值。我的意思是,我只有一个字段用于销售和出租,并且只有一个字段用于住宅和商业(其他字段也是如此)——问题是一处房产可以用于出售或出租,也可以是住宅、商业和工业。
我想我要做的就是将它们移到自己的桌子上。问题是,我还有另一个表列出了每个字段的可能值,该表用于显示值名称、填充表单、用作约束等。
所以现在我陷入了无数的表中。
属性表,值表,然后将这些值连接到属性的表。
一个没有过滤器的普通搜索查询(更多过滤器,更多连接)我有 7 个内部连接。
我很难让连接在查询的 SELECT 部分中约束结果和返回值。
我很感激任何建议,因为这个问题在过去的两天里让我精神疲惫。
编辑:
我目前有下表:
属性
属性_图像
属性_列表
属性_选项
属性_用途
res_geo_address
res_geo_cities
res_geo_neighborhoods
res_geo_states
res_property_options
res_property_type_age
res_property_type_listing
res_property_type_property
res_property_type_ Purpose
res_property_type_ Purpose_property
属性表是主要的属性表,有一些描述属性的列。
properties_ 表用于桥接属性表和 res_property_ 表(使用 ids - 一个用于属性,一个用于值)(图像例外,它仅包含图像记录)
res_ 表列出了属性的 id 和值名称大部分。 (res_geo 表除外)
到目前为止,我的查询不起作用。老实说,我已经达到了如此复杂的程度,以至于我很难解释我当前的设置。
如果有一种简单的方法来查询包含数组的字段的表并轻松检索这些字段,我会很高兴。
编辑 2:
上图显示了其中一个连接。我如何能够查询属性,始终检索与其关联的所有列表名称的串联,但可以选择通过特定的列表 ID 组来限制属性?
Sorry the title couldn't be a more descriptive I still don't know the name of what I'm dealing with.
I'm developing a search system for a realty site and it was working well until I realized I had forgotten to take for account that some of my fields (which are used as filters in the search page) could be multiple values. What I mean is that I had only one field for Sale and Rent and one only one field as well for Residential and Commercial (other fields too) -- the problem is that a property could be for sale or rent or could be residential, commercial and industrial.
What I thought I'd do is move those to their own table. The thing is, I have yet another table that lists the possible values for each field, which is used to display value names, populate forms, used as constraints, etc.
So now I'm stuck with a myriad of tables.
A table for properties, then tables for values, then tables that join these values to the properties.
A plain search query with no filters (more filters, more joins) I'm at 7 inner joins.
I'm having an extremely hard time getting joins to work both for constraining results and returning values in the SELECT portion of the query.
I'd appreciate any suggestions as this problem has left me mentally fatigued for the last 2 days.
EDIT:
I have the following tables at the moment:
properties
properties_images
properties_listings
properties_options
properties_purposes
res_geo_address
res_geo_cities
res_geo_neighborhoods
res_geo_states
res_property_options
res_property_type_age
res_property_type_listing
res_property_type_property
res_property_type_purpose
res_property_type_purpose_property
The properties table is the main property table, has a handful of colums that describe the property.
The properties_ tables are used to bridge the properties table and the res_property_ tables (usings ids - one for the property and one for the value) (exception is the images, which just contains image records)
The res_ tables list id and value names for the most part. (exception are the res_geo tables)
As of right now, my queries don't work. To be honest I've reached such intricacy that is hard for me to explain my current setup.
I'd be nice if there was a simple way to query tables with fields that have arrays and easily retrieve those.
EDIT 2:
The image above shows one of the joins. How would I be able to query for a property, always retrieve a concat of all the listing name associated with it but optionally limit the properties by a certain group of listing ids?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果这就是您所描述的内容:
其中
Property
定义可应用于给定Entity
的各种属性,PropertyValue
定义以下值:对于给定的Property
有效,并且EntityPropertyValue
定义给定Entity
的给定属性的值,那么您所拥有的几乎完全相同EAV(只需将属性
替换为属性
,您就会得到准确的EAV)。这种架构本质上没有任何问题,并且在某些情况下它确实是有效的(并且可能是唯一有效的)选择。您的情况听起来确实适合 EAV。
正如您所发现的,问题在于它会使查询变得困难,尤其是当您允许用户为给定属性指定多个值时。这将使构建结果集变得困难,因为您必须考虑潜在的笛卡尔积。如果没有看到您遇到问题的实际查询,我无法给您任何进一步的建议(请随意编辑您的问题并对我的答案发表评论;如果您这样做,我会修改它并添加一些建议),但我可以告诉你,仅仅拥有“无数的表”并不一定是坏事,事实上,根据你的参数,听起来像是正确的设计选择。
If this is what you're describing:
Where
Property
defines the various properties that can be applied to a givenEntity
,PropertyValue
defines the values that are valid for a givenProperty
, andEntityPropertyValue
defines the value for a given property for a givenEntity
, then what you have is pretty much exactly EAV (just substitute the wordAttribute
forProperty
and you will have exactly EAV).There's nothing inherently wrong with this architecture, and there are certainly some circumstances where it's a valid (and possibly the only valid) choice. Your circumstance does sound like it's a good candidate for EAV.
The trouble, as you've discovered, is that it can make querying difficult, especially when you're going to allow the user to specify multiple values for a given property. This will make constructing your result set difficult, as you're going to have to account for potential cartesian products. I can't give you any further advice without seeing an actual query that you're having trouble with (feel free to edit your question and post a comment on my answer; I'll revise it and add some advice if you do), but I can tell you that simply having a "myriad of tables" is not necessarily bad, and, in fact, sounds like the correct design choice given your parameters.
听起来你是一个非常糟糕的建议的受害者,即对所有内容都使用整数键,即使是只有一个真实列的简单表,其中包含“销售”、“租赁”等值。
你的表 RES_PROPERTY_TYPE_LISTING 应该只有一列“ TypeCode”(使用“code”是我们使用字符主键时的一个非常古老的约定),这是主键。
现在您可以删除一个表,因为 PROPERTIES_LISTINGS 看起来像这样:
至于整数使连接速度更快的想法,我们刚刚消除了 JOIN,而最快的 JOIN 是您不必执行的连接。剩余的 JOIN 仍然是整数,因此当您达到 10,000 trx/秒时您是安全的,因为在此之前您永远不会看到差异。
祝你好运!
Sounds like you are the victim of the very bad advice to use an integer key for everything, even simple tables that have only a single real column with values like 'Sale', 'Rent' etc.
Your table RES_PROPERTY_TYPE_LISTING should have only one column "TypeCode" (using "code" is a very old convention for when we use character primary keys), which is the primary key.
Now you get to drop one table, because PROPERTIES_LISTINGS looks like this:
As for the idea that integers make faster joins, we've just eliminated a JOIN, and the fastest JOIN is the one you don't have to do. The remaining JOIN is still on integers, so you are safe when you hit 10,000 trx/second, because before that you'll never see the difference.
Best of luck!