在 MySQL 中绑定 2 个不同情况下的 3 个表

发布于 2025-01-06 08:37:52 字数 187 浏览 0 评论 0原文

我没有找到解决方案,所以想请教您。

整个事情是我有 3 张表:城市、地区、机构。

  • 区和城市有关系

现在当我想注册一个机构时,我必须选择该机构所属的区,但如果该城市没有任何区,我必须选择城市本身。那么,问题是,如何针对给定情况绑定这些表?

PS 地区和城市必须保持约束力

I did not found a solution to this, so I want to ask you.

The whole thing is that I have 3 tables: Cities, Districts, Institutions.

  • Districts have a relationship with Cities

Now when I want to register an Institution, I have to choose a District from which the Institution belongs, but if that City doesn't have any district, I have to choose the City itself. So, the question is, how can I bind these tables for the given situation?

P.S. the Districts and Cities must remain bind

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

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

发布评论

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

评论(3

此刻的回忆 2025-01-13 08:37:52

有2个表,“机构”和“区域”

允许“区域”链接到自身,即area_id,parent_area_id

这样您总是将机构链接到area_id,然后内部逻辑可以确定该区域是否被视为地区或一座城市。

所以你现在有了

institutions (
    id UNSIGNED INT NOT NULL PK AI,
    area_id UNSIGNED INT NOT NULL,
    name VARCHAR NOT NULL
)

,并且

areas (
    id UNSIGNED INT NOT NULL PK AI,
    parent_area_id UNSIGNED INT NOT NULL DEFAULT 0,
    name VARCHAR NOT NULL,
    type ENUM('city','district') NOT NULL DEFAULT 'city' 
)

Areas.type 字段是可选的,但如果你想这样定义它们,那么这可能是在数据库中执行此操作的一种方法(否则只需假设如果parent_area_id = 0那么它是一个城市,否则它是一个 这样,

当选择字段时,您所做的就是

SELECT *
FROM institutions
INNER JOIN areas
ON areas.id = institutions.area_id

您可以 100% 确定机构 area_id 链接到的位置,对于是否转到“地区”或“城市”表没有问号,它肯定会区域表反过来以相同的方式处理地区和城市,并以前端可能将其解释为城市或地区的格式呈现信息。或者,如果您确实想要的话,您可以更进一步

SELECT
    i.*,
    COALESCE(a_parent.id,a_child.id) AS city_id,
    COALESCE(a_parent.name,a_child.name) AS city_name
FROM institutions AS i
INNER JOIN areas AS a_child
ON a_child.id = i.area_id
LEFT JOIN areas AS a_parent
ON a_parent.id = a_child.parent_area_id 

例如,即使该机构与城市中的特定区域相关联,也始终会返回城市名称

Have 2 tables, "Institutions" and "Areas"

Allow "Areas" to link to itself i.e. area_id, parent_area_id

This way you always link an Institution to an area_id, and then internal logic can deteremine whether that area is considered to be a District or a City.

So you now have

institutions (
    id UNSIGNED INT NOT NULL PK AI,
    area_id UNSIGNED INT NOT NULL,
    name VARCHAR NOT NULL
)

and

areas (
    id UNSIGNED INT NOT NULL PK AI,
    parent_area_id UNSIGNED INT NOT NULL DEFAULT 0,
    name VARCHAR NOT NULL,
    type ENUM('city','district') NOT NULL DEFAULT 'city' 
)

The areas.type field is optional but if you want to define them as such then that may be a way to do that within the database (else just assume that if parent_area_id = 0 then it's a city, else it's a district)

This way when selecting the field all you are doing is

SELECT *
FROM institutions
INNER JOIN areas
ON areas.id = institutions.area_id

You can be 100% certain where the institution area_id links to, there's no question mark over whether to go to the Districts or Cities table, it's definitely going to the areas table which in turn treats Districts and Cities in the same way and presents information in a format which your front end may then interpret as city or district. Optionally you could go a step further if you really wanted to

SELECT
    i.*,
    COALESCE(a_parent.id,a_child.id) AS city_id,
    COALESCE(a_parent.name,a_child.name) AS city_name
FROM institutions AS i
INNER JOIN areas AS a_child
ON a_child.id = i.area_id
LEFT JOIN areas AS a_parent
ON a_parent.id = a_child.parent_area_id 

That for example would always return the city name even if the institution was tied to a specific district within a city

陌伤ぢ 2025-01-13 08:37:52

有一种肮脏、重复肮脏的方式来做到这一点:让机构有一个SIGNED INT类型的ID字段,负数指向城市的 ID,以及指向该地区的正数。这有助于轻松连接查询。

再次强调:这是肮脏的,我建议您完全避免这种情况(例如,通过创建具有父字段的城市和地区的树表),但如果您无法更改模型,那么这是可行的。

There is a dirty, repeat dirty way of doing this: Have the institution have an ID field of type SIGNED INT, with negative numbers pointing to the ID of the City, and positive numbers pointing to the District. This does for easy joins on query.

Again: This is dirty, I recommend you avoid the situation alltogether (e.g. by creating a tree-table of cities and districts with a parent field), but if you can't change your model, this works.

爱*していゐ 2025-01-13 08:37:52

这种模式称为多态关联,用 SQL 很好地解决它并不容易。

uid // common id table with globally unique ids
  id int AUTO_INCREMENT

city
  id UNIQUE FK:uid.id

district
  id UNIQUE FK:uid.id
  city_id FK:city.id

institution
  location_id FK:uid.id 

fruits
  id UNIQUE FK:uid.id

FK 表示外键。您必须手动检查 institution.location_id 是否指向一个地区或城市,而不是水果或其他任何东西。

This pattern is called polymorph associations, and it's not easy to solve nicely with SQL.

uid // common id table with globally unique ids
  id int AUTO_INCREMENT

city
  id UNIQUE FK:uid.id

district
  id UNIQUE FK:uid.id
  city_id FK:city.id

institution
  location_id FK:uid.id 

fruits
  id UNIQUE FK:uid.id

FK means foreign key. You have to check manually that institution.location_id points to a district or city, not a fruit, or whatever else.

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