0

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

例如,我有一个用户表。

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

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

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

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

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

表二国家列表:国家列表和每个国家的各自ID

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 个与上述类似的表格,提供有关用户的详细信息;即使用的语言、年龄组、国籍等。

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

所以,我真的要求一些关于最有效/正确的数据库规划方式的建议。

4

2 回答 2

0

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

您的SELECT查询将看起来像

SELECT * FROM Users
WHERE Country_ID = (
    SELECT Country_ID FROM Countries
    WHERE Country_Name = 'USA'
);
于 2013-10-05T14:33:55.730 回答
0

如果您将拥有大量数据,那么您应该保持相同的方法并使用以下方法来满足一对一的约束

如果您没有大量数据,那么您应该保留国家/地区之类的查找表,并在列中使用用户的参考。但是您可能需要允许它们为空,这使得这些可选信息列可以为空。

最有效和完全正确的方法是首先从第三张表“user_countrylocation”中删除数据,以便更新用户。然后为用户插入新位置。不要忘记使用事务。

你的表 3 应该有

country_id MEDIUMINT UNSIGNED NOT NULL,

代替

country_id VARCHAR(60) NOT NULL,

并将所有表中的列名从 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
于 2013-10-05T15:07:58.720 回答