成千上万的城市和用户关系,什么是正确的方式?

时间:2012-12-19 18:46:26

标签: php mysql database

在一个应用程序中,允许用户选择他们想要的位置/城市。城市列表将采用树形结构,其复选框如下:

[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。 查找表是否理想?或者我可以在文本类型列中以json格式将所有位置id kand存储为盛大吗?

谢谢!

3 个答案:

答案 0 :(得分:3)

  

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

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

  

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

没有。这不是一个正常的形式。它会产生很多问题。您无法轻松执行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`)    
  );

答案 1 :(得分:0)

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

但是,如果您需要能够查找具有所选国家/地区,州或城市的所有用户,那么您需要存储数据,以便以这种方式查询数据。这可能意味着具有表格的国家,州和城市的单独表格将用户与每个表格相关联,或者它可以简单地表示允许其中的不同类型的管辖区域的单个管辖权表格以及将用户与管辖区域相关联的表格。您如何处理模式可能取决于您需要将国家,州和城市彼此区别对待的方式(即每个管辖区类型需要具有截然不同的属性)。

答案 2 :(得分:0)

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

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

它将简化您的创建,更新和删除操作:而不是写入数百或数千行,每个更改只会影响一行。