简体   繁体   English

ER_NON_UNIQ_ERROR以及如何正确设计表

[英]ER_NON_UNIQ_ERROR and how to design tables correctly

I have come across this problem and I've tried to solve it few days now. 我遇到过这个问题,现在几天我试图解决它。

Let's say I have following tables 假设我有以下表格

properties 性能

-----------------------------------------
|  id  |  address  |  building_material |
-----------------------------------------
|   1  |  Street 1 |         1          |
-----------------------------------------
|   2  |  Street 2 |         2          |
-----------------------------------------

building_materials 建筑材料

-----------------------------
|  id  |  building_material |
-----------------------------
|   1  |        Wood        |
-----------------------------
|   2  |       Stone        |
-----------------------------

Now. 现在。 I would like to provide an API where you could send a request and ask for every property that has building material of wood. 我想提供一个API,您可以发送请求并要求每个拥有木材建筑材料的房产。 Like this: 像这样:

myapi.com/properties?building_material=Wood myapi.com/properties?building_material=Wood

So I would like to query database like this (I want to return the string value of building_material not the numeric value): 所以我想像这样查询数据库(我想返回building_material的字符串值而不是数值):

SELECT p.id, p.address, bm.building_material 
FROM properties as p 
JOIN building_materials as bm ON (p.building_material = bm.id) 
WHERE building_material = "Wood"

But this will give me an error 但这会给我一个错误

Column 'building_material' in where clause is ambiguous where子句中的'building_material'列不明确

Also if I want to get property with id of 1. 此外,如果我想获得id为1的属性。

SELECT p.id, p.address, bm.building_material 
FROM properties as p 
JOIN building_materials as bm ON (p.building_material = bm.id) 
WHERE id = 1

Column 'id' in where clause is ambiguous where子句中的列'id'是不明确的

I understand that the error means that I have same column name in two tables and I don't specify which id I want like p.id. 我理解错误意味着我在两个表中有相同的列名,而且我没有指定我想要的p.id.

Problem is I don't know how many query parametes API user is going to send and I would like to avoid looping through them and changing id to p.id and building_material to bm.building_material . 问题是我不知道有多少查询参数API用户要发送,我想避免循环遍历它们并将id更改为p.id并将building_material更改为bm.building_material Also I don't want that user has to send request to the API like this 此外,我不希望用户必须像这样向API发送请求

myapi.com/properties?bm.building_material=Wood myapi.com/properties?bm.building_material=Wood

I've thought about changing the properties table building_material to fk_building_material and changing properties table id to property_id . 我已经考虑过将属性表building_material更改为fk_building_material并将属性表id更改为property_id

I just don't like the idea that on client side I would then have to refer property's building material as fk_building_material. 我只是不喜欢在客户端我必须将属性的建筑材料称为fk_building_material的想法。 Is this a valid method to solve this problem or what would be the correct way of designing these tables? 这是解决此问题的有效方法,还是设计这些表的正确方法?

The query mentions two tables, so all the columns in both tables are "on the table" for use anywhere in the query. 该查询提到了两个表,因此两个表中的所有列都“在表上”,以便在查询中的任何位置使用。

In one table building_material is an "id" for linking to the other table; 在一个表中, building_material是用于链接到另一个表的“id”; in the other table, it is a string. 在另一个表中,它是一个字符串。 While this is possible, it is confusing to the reader. 虽然这是可能的,但这对读者来说很困惑。 And to the parser. 并解析器。 To resolve the confusion, you must qualify building_material with which one you want; 要解决这种混淆,您必须使building_material符合您的要求; that is done with a table alias (or table) in front (as you did in all other places). 这是通过前面的表别名(或表)完成的(就像你在其他所有地方所做的那样)。

There are two ids are all ambiguous. 有两个ids都是模棱两可的。 But this is the "convention" used by table designers. 但这是表设计者使用的“惯例”。 So, it is OK for an id in one table to be different than the id in the other table. 因此,它是确定一个id在一个表中比在其他表中的id不同。 ( p.id refers to one thing in one table; bm.id refers to another in another table.) p.id指的是一个表中的一个; bm.id指的是另一个表中的另一个。)

SELECT p.id, p.address, bm.building_material 
    FROM properties as p 
    JOIN building_materials as bm ON (p.building_material = bm.id)
    WHERE bm.building_material = "Wood"  -- Note "bm."

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM