当有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多个类似的表,提供有关用户的详细信息;即语言,年龄组,国籍等。
我担心的是,如果我将这个独特的信息放在用户表的每个用户列中,那么搜索数据库的最有效方法是什么:这就是我选择上述风格的原因。
所以,我真的要求就最有效/正确的数据库规划方法提出一些建议。
答案 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