将数据放入表OneToONe的正确方法

时间:2013-10-05 14:28:29

标签: mysql sql

当有OneToOne关系时,我对在dababase表中放置数据的正确/最有效方法感到困惑。

例如,我有一个用户表。

我现在希望每个用户能够说明他当前的国家/地区位置。

然后,我希望能够按当前位置搜索数据表中的用户。

我这样做的方法是创建3个单独的表。即

表一 - 用户:只包含用户信息:

CREATE TABLE users(
id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT,
firstName VARCHAR(30) NOT NULL,
lastName VARCHAR(40) NOT NULL,
);  

表二国家/地区列表:每个国家/地区的国家/地区列表

PHP Code:
CREATE TABLE countrylist(
country_id MEDIUMINT UNSIGNED NOT NULL, 
country VARCHAR(60) NOT NULL,
INDEX country_id ( country_id, country ), 
INDEX countrylist (country, country_id ), 
UNIQUE KEY (country)

); 

表3;包含userId和他居住的countryId:

PHP Code:
CREATE TABLE user_countrylocation(
country_id VARCHAR(60) NOT NULL,
id MEDIUMINT UNSIGNED NOT NULL, 
INDEX country_id (country_id, id ), 
INDEX user_id (id, country_id ) 
);  

或者,我应该将countryId放在users表中并完全摆脱user_countrylocation。即在每个用户专栏中,我将为他所居住的国家/地区设置country_id。

问题是我有20多个类似的表,提供有关用户的详细信息;即语言,年龄组,国籍等。

我担心的是,如果我将这个独特的信息放在用户表的每个用户列中,那么搜索数据库的最有效方法是什么:这就是我选择上述风格的原因。

所以,我真的要求就最有效/正确的数据库规划方法提出一些建议。

2 个答案:

答案 0 :(得分:0)

一对一关系通常通过将两个表链接在一起的外键来映射。只有多对多关系才需要第三个映射表。因此,理想情况下,您的Country_ID表格中应该有一个外键Users

您的SELECT查询将如下所示

SELECT * FROM Users
WHERE Country_ID = (
    SELECT Country_ID FROM Countries
    WHERE Country_Name = 'USA'
);

答案 1 :(得分:0)

如果您要获得大量数据,那么您应该采用相同的方法并使用以下方法来保持一对一约束

如果您没有庞大的数据,那么您应该像国家一样保留查找表,并在列中使用用户的引用。但是你可能需要允许它们使这些可选信息列成为可空的空值。

最有效和最准确的方法是首先从第三个表“user_countrylocation”中删除要更新的用户的数据。然后为用户插入新位置。不要忘记使用交易。

你的桌子3应该有

country_id MEDIUMINT UNSIGNED NOT NULL,

而不是

country_id VARCHAR(60) NOT NULL,

并在所有表格中将tyhe列名称从id更改为user_id。

如果您使用的是存储过程,那就像

create procedure sp_UpdateUserCurrentCountry (
                 @userID MEDIUMINT UNSIGNED,
                 @CountryID MEDIUMINT UNSIGNED)

begin 
as
   delete from user_countrylocation
   where user_id = @userID

insert into user_countrylocation
           (
           country_id,
           user_id
           )
 values
           (
           @CountryID,
           @userID
           )
END