假设我有一个包含这种模式的数据库:
Product
-------
ProductID
Name
Price
Attribute1ID
Attribute2ID
Attribute3ID
Attribute4ID
Attribute5ID
...
Attribute1
----------
Attribute1ID
Attr_name
Attribute2
----------
Attribute2ID
Attr_name
Attribute3
----------
Attribute3ID
Attr_name
现在,我正在尝试创建目录,并希望能够根据其属性过滤产品。 e.g。
SELECT p.Name, p.Price
FROM Product p
JOIN Attribute1 a1 USING (Attribute1ID)
JOIN Attribute2 a2 USING (Attribute2ID)
WHERE (a1.Attr_name = [some value])
AND (a2.Attr_name = [some value]);
我想在PHP中动态创建(例如,根据GET数据)这样的查询。我关心的是如何/在哪里存储表名和主键,以便我的PHP代码可以组装查询。
将此信息简单地存储在PHP文件的数组中是否合适? e.g。
$tableAndPK['attr-1'] = array('table'=>'Attribute1','pk'=>'Attribute1ID');
$tableAndPK['attr-2'] = array('table'=>'Attribute2', 'pk'=>'Attribute2ID');
$tableAndPK['attr-3'] = array('table'=>'Attribute3', 'pk'=>'Attribute3ID');
// etc... where 'attr-x' is the corresponding form input name.
或者将这些信息放在另一个表中是否更明智?每次加载目录时都可以从数据库中检索这些信息? e.g。
SELECT HtmlName, TableName, PrimaryKey
FROM AttributeMetadata
WHERE HtmlName IN ([form input names that are required]);
或者或许还有(n)(显然更好)的方式来解决这个问题?我可以研究一些设计模式,或PHP或MySQL中预先存在的可能对我有帮助的机制?
谢谢。
答案 0 :(得分:1)
您可能很快就会讨厌使用这样的架构。如果您的架构看起来更像这样,我强烈建议您将极大地简化您的任务:
Product
-------
ProductID
Name
Price
Attributes
----------
AttrID
Attr_name
ProdAttribMap
-------------
ProductID
AttrID
然后通过Product
加入Attributes
到ProdAttribMap
,如下所示:
select
*
from
Product
left join ProdAttribMap on Product.ProductID = ProdAttribMap.ProductID
left join Attributes on ProdAttribMap.AttrID = Attributes.AttrID
where
Attr_name = "blah"
;
要执行某些操作,您可以只使用上面的一个简单连接,有时可能需要多次连接属性,并应用不同的where
子句,但现在您只有这样的情况EVER有3个表,因此您不需要存储任何元数据。
此外,您可以拥有任意数量的属性而无需更改数据库的架构,因此维护更容易。
请注意,这里的单词属性IMO有点狡猾,因为你使用的是没有名字的值,我想说这意味着它们实际上是标签,而不是属性,但它是一个小的术语投诉
如果您真的在做属性,要完全非规范化,您可以像这样更改Attributes
表:
Attributes
----------
AttrID
AttrNameID
Attr_value
并添加一个新表:
AttributeNames
--------------
AttrNameID
Attr_name
属性名称表将包含Attr_name
个值,例如' age'或者'性别',而像' 30'和男性'将位于Attr_value
表的Attributes
列中。
答案 1 :(得分:0)
如果它是一个更大的应用程序,我建议您使用ORM来处理所有这些事情。
那里有很多ORM,比如教条可以为你处理所有的关系。
通过使pk可配置,您要做的是构建自己的ORM。