【问题标题】:Thousands of Cities and Users relationship, what's the right way?千城万户与用户关系,何为正道?
【发布时间】:2012-12-19 18:46:25
【问题描述】:

在一个应用程序中,用户可以选择他们想要的位置/城市。城市列表将采用带有复选框的树结构,例如:

[x]Country
-[x]State 1
--[x]City 1
--[x]City 2
--[x]City 100
-[X]State 2
--[x]City 1
--[x]City 2
--[x]City 100
[x]Country 2

......

现在,如果用户选择国家,那么他将拥有所有州和城市。如果选择一个或多个州并且那些州、城市和国家也将被存储为该用户。用户可以选择一个或多个国家。用户也可以取消选中任何一个想要的城市或州。

您建议如何存储和检索数据。我正在使用 MySql 和 PHP。 查找表会是理想的吗?或者我可以将所有位置 id kand 以 json 格式存储在文本类型列中吗?

谢谢!

【问题讨论】:

  • 要格式化代码块,突出显示它并 ctl-k,或单击编辑器中的 { } 按钮。反引号用于内联代码,实际上不适用于多行块。
  • 感谢编辑,不太熟悉。

标签: php mysql database


【解决方案1】:

您建议如何存储和检索数据。我正在使用 MySql 和 PHP。查找表会是理想的吗?

要存储国家、州和城市,您应该使用规范化的数据库架构。国家有州。州有城市。您需要连接表。

或者我可以将所有位置 id kand 以 json 格式存储在文本类型列中吗?

没有。那将不是一个正常的形式。而且会产生很多问题。您不能轻松地执行 CRUD 操作。

数据库架构

create table countires(name varchar(100) primary key);
create table sates(name varchar(100) primary key, country varchar(100), foreign key `country` references `countries`(`name`)); 
create table cities(name varchar(100) primary key, state varchar(100), foreign key `state` references `states`(`name`)); 

现在您可以对这些表运行任何不同类型的查询。假设用户选择了城市(city1city2)、国家/地区cntry1 和州stt2

查询

查找用户选择的所有城市。

SELECT ct.name 
FROM   cities AS ct 
       JOIN states AS st 
         ON ( st.name = city.state ) 
       JOIN countries AS cn 
         ON ( cn.name = st.country ) 
WHERE  ct.name IN ( 'city1', 'city2' ) 
        OR cn.name = 'cntry1' 
        OR st.name = 'stt2'; 

查找用户选择的所有状态。

SELECT st.name 
FROM   states AS st 
       JOIN countries AS cn 
         ON ( cn.name = st.country ) 
WHERE   OR cn.name = 'cntry1' 
        OR st.name = 'stt2'; 

更新 1

如何维护与用户的关系?

您需要Junction tables。只需创建 3 个即可。

create table users(name varchar(100) primary key);
CREATE TABLE user_countries 
  ( 
     user    VARCHAR(100), 
     country VARCHAR(100), 
     PRIMARY KEY (`user`, `country`), 
     FOREIGN KEY (`user`) REFERENCES `users`(`name`)
     FOREIGN KEY (`counry`) REFERENCES `countries`(`name`)    
  ); 
CREATE TABLE user_states 
  ( 
     user    VARCHAR(100), 
     state   VARCHAR(100), 
     PRIMARY KEY (`user`, `state`), 
     FOREIGN KEY (`user`) REFERENCES `users`(`name`) 
     FOREIGN KEY (`state`) REFERENCES `states`(`name`)    
  ); 
CREATE TABLE user_cities 
  ( 
     user    VARCHAR(100), 
     city    VARCHAR(100), 
     PRIMARY KEY (`user`, `city`), 
     FOREIGN KEY (`user`) REFERENCES `users`(`name`) 
     FOREIGN KEY (`city`) REFERENCES `cities`(`name`)    
  );

【讨论】:

  • 谢谢,但我的问题是如何保持与用户的关系?
  • 感谢您的快速回复。您对将其存储为 json 对象有何看法?
【解决方案2】:

我会说这取决于您需要如何访问存储的数据。如果您只是要根据提交数据的用户来查找数据,那么您可能没有理由不能将序列化的树数据(即 JSON、PHP 序列化等)存储在与关联的数据库记录中用户。顺便说一句,这也是 NoSQL 数据存储的一个很好的用例。

但是,如果您需要能够查找所有选择了特定国家、州或城市的用户,那么您将需要存储您的数据,以便以这种方式进行查询。这可能意味着国家、州和城市使用单独的表格来将用户与每个表格关联起来,或者它可能只是意味着一个单一的管辖范围表,该表格允许其中包含不同类型的管辖区以及将用户与管辖区相关联的表格。您如何处理该架构可能取决于您需要将国家、州和城市彼此区别对待(即每种司法管辖区类型是否需要具有截然不同的属性)。

【讨论】:

  • 我需要对其进行所有 CRUD 操作。但是你不觉得用查表会臃肿吗?
  • 您需要一些机制来确定用户与所选司法管辖区之间的关系。如果你有正确索引表,性能应该没问题。
【解决方案3】:

我建议只存储选定的值并导出其余值。是的,检索数据会有点痛苦,但它有几个显着的好处:

当您的源数据发生变化时,它仍将保持准确:想象一下,当苏联解体时,您正在运行此应用程序。您将“苏联”条目转换为“俄罗斯”并将一堆“国家”转换为国家。使用您的模型,这将导致大量用户数据被更改。但是,使用派生模型,这变得更加简单。当城市被分配到正确的国家时,任何选择了城市的人都会自动修复。选择了一个州的一群人可能会突然发现他们选择了一个国家,但该级别以下的城市是自动固定的。

它将简化您的创建、更新和删除操作:每次更改都只影响一行,而不是编写成百上千行。

【讨论】:

    猜你喜欢
    • 2014-12-29
    • 1970-01-01
    • 2018-02-14
    • 2014-11-19
    • 1970-01-01
    • 1970-01-01
    • 2013-04-13
    • 1970-01-01
    • 2021-05-04
    相关资源
    最近更新 更多