mysql数据库有很多很多关系混乱

时间:2016-01-03 05:20:43

标签: php mysql many-to-many

我有4张桌子

集线器|国家|类别|消息

这里的枢纽和国家有很多关系

country_hub

id   
hub_id    
country_id

然后这个数据透视表country_hub与类别有很多关系,所以我喜欢

category_country_hub

id   
country_hub_id   
category_id   

这个表与新闻表有很多关系

category_country_hub_news

category_country_hub_id      
news_id   

这给了我一个复杂的查询关系

所以我想改变像

这样的关系

country_hub

country_id   
hub_id

category_country_hub

country_id   
hub_id   
category_id

category_country_hub_news

hub_id   
country_id   
category_id   
news_id   

与中心/国家/类别的一对多关系

有没有更好的方法来处理这种关系请帮助或任何教程链接

1 个答案:

答案 0 :(得分:0)

好的,现在清楚。下面的扩展评论,摘要如下:

TL; DR:
1)你修改后的方法对我更有意义。
2)你的命名约定可以使用一些润色,可以提高人类的可读性(特别是表格中匹配列表顺序的'令牌,fwiw数据库本身不会关心)。
3)书:我将推荐" SQL for Smarties" (Celko),介绍了您正在处理的一些建模问题。 http://www.amazon.com/Joe-Celkos-Smarties-Fourth-Edition/dp/0123820227

让我们深入了解表格定义......我无法从文本摘要中得出理由,如果能够看到示例,我的大脑会更好。

让我知道这些例子是(或多或少)合适的。

原始数据表

似乎可以调用这些事实表。

|-----------------|---------------|---------------|--------------------|
| select * from   | select * from | select * from | select * from      |
| COUNTRIES       | HUBS          | CATEGORIES    | NEWS               |
|-----------------|---------------|---------------|--------------------|
|  id :   name    |   id : name   |  id : name    |    id :   title    |
| --- : --------- |  --- : -----  | --- : ------- |  ---- : -----------|
| 101 : China     |  201 : X      | 301 : Red     |   401 : 'aa aaaa a'|
| 102 : Nepal     |  202 : Y      | 302 : Blue    |   402 : 'bbbb b bb'|
| 103 : Australia |  203 : Z      | 303 : Green   |   403 : 'cc ccc cc'|
| 104 : NewZealand|  ...etc...    | 304 : Orange  |   404 : 'ddddd d'  |
|   ...etc...     |               | ...etc...     |   405 : 'ee eeee'  | 
|-----------------|---------------|---------------|--------------------|

原始关系表

观察:这些不是维度表,我在这里看不到明显的层次结构。

让我们进一步说明这一点。

  |-----------------------|---------------------------|--------------------------|
  | select * from         | select * from             | select * from            |
  | COUNTRY_HUB           | CATEGORY_COUNTRY_HUB      | CATEGORY_COUNTRY_HUB_NEWS|
  |-----------------------|---------------------------|--------------------------|
  |     :        : country|    : country  :  category |        cat_cnt  : news   |
  |  id : hub_id : _id    | id :  _hub_id :  _id      |  id  : _hub_id  : _id    |
  |---- : ------ : -------|----: -------- : ----------| ---- : -------- : ------ |
  |  11 :    101 :  201   | 21 :     11   :   301     |  31  :    21    :   401  |
  |  12 :    101 :  202   | 22 :     11   :   303     |  32  :    21    :   403  |
  |  13 :    101 :  203   | 23 :     12   :   302     |  33  :    21    :   404  |
  |  14 :    102 :  200   | 24 :     12   :   304     |  34  :    22    :   405  |
  | ...etc...             | ...etc...                 |  ...etc...               |
  |-----------------------|---------------------------|--------------------------|

是的,这看起来很复杂。 : - )

观察:如果你将继续采用这种方法,我认为如果你这样做会更容易一些 遵循最后嵌入原始数据表的命名约定:

 Original tbl names         |    Notes
----------------------------|------------------------------------------------------
COUNTRY_HUB                 | Two raw-data id#'s (hub_id & country_id)s
----------------------------|------------------------------------------------------
CATEGORY_COUNTRY_HUB        | One raw data id#, last column (category_id), but CATEGORY_... first
                            | token in the table name.
                            | I will suggest COUNTRY_HUB_CATEGORY would be easier to read
                            | for human readers, since both right-most column and right-most token
                            | in the table name tie back to the same concept (the CATEGORY raw data table).
----------------------------|------------------------------------------------------
CATEGORY_COUNTRY_HUB_NEWS   | One raw data id#, last column (news_id), also _NEWS  is last token
                            | in the table name, easier for human readers to parse & follow.
----------------------------|------------------------------------------------------

修改后的关系表

这看起来更好。

  |-----------------------|-------------------------------|-------------------------------------------|
  | select * from         | select * from                 | select * from                             |
  | COUNTRY_HUB           | CATEGORY_COUNTRY_HUB          | CATEGORY_COUNTRY_HUB_NEWS                 |
  |-----------------------|-------------------------------|-------------------------------------------|
  |     : country: hub    |    : country : hub  : category|      : hub   : country : category : news  |
  |  id : _id    : _id    | id : _id     : _id  :  _id    |  id  : _id   : _id     : _id      : _id   |
  |---- : ------ : -------|----: --------: ---- : --------| ---- : ----- : ------- : -------- : ----- |
  |  11 :    201 :  101   | 21 : 201     :  101 :  301    |  31  :  101  :    201  :  301     : 401   |
  |  12 :    202 :  101   | 22 : 201     :  101 :  302    |  32  :  101  :    201  :  301     : 401   |
  |  13 :    203 :  102   | 23 : 201     :  101 :  303    |  33  :  102  :    201  :  301     : 401   |
  |  14 :    204 :  102   | 24 : 201     :  102 :  301    |  34  :  102  :    201  :  301     : 402   |
  | ...etc...             | ...etc...                     |  ...etc...                                |
  |-----------------------|-------------------------------|-------------------------------------------|

关于命名约定 表名"令牌"仍然不遵循列顺序。 作为对自己和未来维护者的青睐,请考虑改变:

COUNTRY_HUB is fine.
CATEGORY_COUNTRY_HUB still seems flipped, use COUNTRY_HUB_CATEGORY
CATEGORY_COUNTRY_HUB_NEWS doesn't follow from previous, I would use COUNTRY_HUB_CATEGORY_NEWS and adjust the columns accordingly (though I
don't know enough about your data relationships to comment on what is
the best order).

您在命名中隐含的内容是粗略的"类别"

overly simplistic:
   Each COUNTRY has 0..many HUBS.
   Each HUB has 0..many CATEGORIES.
   Each CATEGORY  has 0..many NEWS items.

我建议你努力制作你的桌名"代币"匹配"列顺序"。 你似乎有(按照少数到多数):

COUNTRY  : COUNTRIES (relatively few)
HUB      : HUBS (# of HUBS greater than # of COUNTRIES)
CATEGORY : Assigned CATEGORIES (# of COUNTRY+HUB+CATEGORY combinations exceeds # of previous)
NEWS     : Assigned NEWS items (# of COUNTRY+HUB+CATEGORY+ combinations exceeds # of previous)

让我们做一点数据建模并描述关系...

COUNTRY <*----*> HUB
   Each COUNTRY has 0..many HUBS.  
   A given HUB may be associated w/multiple COUNTRIES.


HUB ----*> CATEGORY
or..?
COUNTRY + HUB <*----*> CATEGORY
   Your tables suggest CATEGORIES do not simply associate directly with a given HUB.
   Consider HUB.id=101 name='X' 
      X.China.categories = ( Blue, Yellow );
      X.Nepal.categories = ( Orange, Green );
      X.Australlia.categories = ( ); e.g. none.

   Instead of all countries associated with that HUB sharing the same "HUB CATEGORIES",
   it sounds like the CATEGORIES are like "tags" and that the various countries involved
   with a given HUB can have their collection of 0..many CATEGORIES.
   It seems weird, but I don't know your data.
   In the interests of simplifying I would try to make CATEGORIES be HUB-specific, not
   HUB+COUNTRY specific... but that may be unavoidable for you.

COUNTY + HUB + CATEGORY <*----*> NEWS
   This suggests that a given NEWS item can be associated with 2+ (COUNTRY+HUB+CATEGORY) triples.
   If that is what you need, then it can't be avoided.

您将面临挑战,保持所有关系的最新状态。

您将需要研究外键约束和级联删除。

我非常喜欢这本书:适用于Smarties的SQL(Celko),它介绍了您正在处理的一些建模问题。

将它们按照您的方式拆分可以避免一些异常(Celko使用的一个例子涉及学校的课程安排:教师,班级,房间,学生以及他们之间的关系)。我会推荐这本书,我认为它读得很好。