分层数据库菜单

时间:2011-02-16 07:35:35

标签: mysql database

我一直在查看有关从数据库中选择分层内容的帖子,但我仍然怀疑如何实现以下内容: 我有三张桌子:

  • 地点:我在这里存储一个位置及其对应的父母(例如Europe-> UK-> London)。
  • 建筑物:我在这里存放建筑物。一栋建筑必须在一个地方。
  • 用户位置:此处我存储了特定用户将能够看到的位置。
  • 用户建筑物:我在这里存储特定用户将能够看到的建筑物。

请注意,管理员可以说:“用户1将看到来自日本的所有建筑物,并且他也能够看到来自法国的特定建筑物,但只能看到那个”。

尽管如此,我想建立一个菜单(针对特定用户),类似于:

  • 建筑物
    • 欧洲
      • 德国
        • 慕尼黑
          • Building_1
          • Building_2
      • UK
        • 伦敦
          • Building_3

我对如何获取这些信息有一些疑问,我将不胜感激。

编辑:

表格结构:

1)建筑物

  • Id(主键)
  • 姓名,描述,......
  • location_ID(位置表的外键)
  • Company_ID(公司表的外键......建筑物必须只属于一家公司)。

2)地点

  • Id(主键)
  • 名称
  • 父ID(表格本身的外键......例如:伦敦条目将有一个英国入境的外键。

3)公司

  • Id(主键)
  • 姓名,描述......

4)用户

  • Id(主键)
  • Company_ID(此用户公司的外键(用户只属于一家公司)。

5)用户建筑

  • Id_User(用户表的外键)
  • Id_Building(构建表的外键)

6)用户位置

  • Id_User(用户表的外键)
  • Id_Location(位置表的外键)

这个想法是公司可以分配用户可以看到的建筑物。公司可以分配特定的建筑物(不依赖于位置),这就是用户建筑表的存在,以及它们也可以分配位置的原因,因此用户将看到属于该位置的所有建筑物。

感谢您的评论,我希望我已经澄清了一点。

感谢。

1 个答案:

答案 0 :(得分:1)

如果你想坚持使用当前的数据库模式,问题是位置似乎没有固定数量的级别,所以你必须做一个丑陋的循环来获取user_location.id_location的子级别他们的建筑。 如果您能够区分有意义的类别(如地区,国家,城市)中的位置级别,那将会有很大帮助。这样你就可以有这样的表定义:

CREATE TABLE buildings (
    id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL,
    ...
    region_id INTEGER UNSIGNED NOT NULL,
    country_id INTEGER UNSIGNED NOT NULL,
    city_id INTEGER UNSIGNED NOT NULL,
    PRIMARY KEY (id),
    INDEX (region_id),
    INDEX (country_id),
    INDEX (city_id),
    FOREIGN KEY (region_id) REFERENCES locations(id) ON DELETE RESTRICT,
    FOREIGN KEY (country_id) REFERENCES locations(id) ON DELETE RESTRICT,
    FOREIGN KEY (city_id) REFERENCES locations(id) ON DELETE RESTRICT
) TYPE=InnoDB;

CREATE TABLE user_location (
    user_id INTEGER UNSIGNED NOT NULL,
    location_id INTEGER UNSIGNED NOT NULL,
    PRIMARY KEY (user_id, region_id, country_id, city_id),
    INDEX (user_id),
    INDEX (location_id),
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
    FOREIGN KEY (location_id) REFERENCES locations(id) ON DELETE CASCADE
) TYPE=InnoDB;

然后你可以像这样检索你的建筑物:

SELECT * FROM buildings WHERE id IN (
    (SELECT building_id FROM user_buildings WHERE user_id = ?)
    UNION
    (SELECT id FROM buildings 
    LEFT JOIN user_location ON 
    (user_location.location_id = buildings.region_id
        OR user_location.location_id = buildings.country_id
        OR user_location.location_id = buildings.city_id)
    WHERE user_id = ?)
);

返回的行将包含构建树所需的信息。