S*******C 发帖数: 822 | 1 英文原文
Design database for querying interest/likes of site users.
Assume that number of users is over 6 billion.
下面的答案对吗?
create database usersByInterests;
use usersByInterests;
create table Users(
user_id numeric(10,0) PRIMARY KEY,
email VARCHAR(45) not NULL,
userPassword VARCHAR(45) not NULL,
firstName VARCHAR(45) not NULL,
lastName VARCHAR(45) not NULL
);
create table Interest(
interest_id int PRIMARY KEY,
interest VARCHAR(45) not NULL
);
create table UsersByInterests(
user_id numeric(10,0) not null,
interest_id int not null,
INDEX `user_id` (`user_id` ASC),
PRIMARY KEY (user_id, interest_id),
CONSTRAINT user_id
FOREIGN KEY (user_id)
REFERENCES users (user_id)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT interest_id
FOREIGN KEY (interest_id)
REFERENCES interest (interest_id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
);
insert into users values (1, '[email protected]
/* */', 'aa', 'Tom', 'Cruise');
insert into users values (2, '[email protected]
/* */', 'ba', 'Tom', 'Cruise');
insert into users values (3, '[email protected]
/* */', 'ca', 'Tom', 'Cruise');
insert into users values (4, '[email protected]
/* */', 'da', 'Tom', 'Cruise');
insert into users values (5, '[email protected]
/* */', 'ea', 'Tom', 'Cruise');
insert into users values (6, '[email protected]
/* */', 'fa', 'Tom', 'Cruise');
insert into interest values (1, 'hiking');
insert into interest values (2, 'boating');
insert into interest values (3, 'swimming');
insert into interest values (4, 'dancing');
insert into interest values (5, 'skiing');
insert into UsersByInterests values (1, 1);
insert into UsersByInterests values (1, 2);
insert into UsersByInterests values (1, 3);
insert into UsersByInterests values (1, 4);
insert into UsersByInterests values (1, 5);
insert into UsersByInterests values (2, 2);
insert into UsersByInterests values (2, 3);
insert into UsersByInterests values (2, 4);
insert into UsersByInterests values (2, 5);
insert into UsersByInterests values (3, 2);
insert into UsersByInterests values (3, 3);
insert into UsersByInterests values (3, 4);
insert into UsersByInterests values (3, 5);
SELECT * FROM usersbyinterests.usersbyinterests where interest_id = 2;
SELECT * FROM usersbyinterests.usersbyinterests where user_id = 2; | j******o 发帖数: 4219 | 2 你要快速搜索就不能这样用3个表,每次查询要查3个表肯定慢。把interest做到user表
里面去。 | S*******C 发帖数: 822 | 3 好办法,但每个user可以有多个interest,怎么把它们都整到一个attribute里?
我可以用特殊支付分割,比如1_2_5,表示该用户有1,2,5三种interest,这种写法在
update interest的时候很慢。有没有更好的方法
【在 j******o 的大作中提到】 : 你要快速搜索就不能这样用3个表,每次查询要查3个表肯定慢。把interest做到user表 : 里面去。
| j******o 发帖数: 4219 | 4 interest一共才几十个,哪怕每个做一个field都可以。更优化的办法就要慢慢想了。
【在 S*******C 的大作中提到】 : 好办法,但每个user可以有多个interest,怎么把它们都整到一个attribute里? : 我可以用特殊支付分割,比如1_2_5,表示该用户有1,2,5三种interest,这种写法在 : update interest的时候很慢。有没有更好的方法
| H*******g 发帖数: 6997 | 5 sounds like mongodb
【在 j******o 的大作中提到】 : 你要快速搜索就不能这样用3个表,每次查询要查3个表肯定慢。把interest做到user表 : 里面去。
| S*******C 发帖数: 822 | 6 不过我查询的时候不需要查3个表,只要查第三个表就够了
就是在第三个表每插入一行得check foreign key是否有效
【在 j******o 的大作中提到】 : 你要快速搜索就不能这样用3个表,每次查询要查3个表肯定慢。把interest做到user表 : 里面去。
| j******o 发帖数: 4219 | 7 给你一个interest name,要求列出所有用户名,你就知道痛苦了。
【在 S*******C 的大作中提到】 : 不过我查询的时候不需要查3个表,只要查第三个表就够了 : 就是在第三个表每插入一行得check foreign key是否有效
| S*******C 发帖数: 822 | 8 我有一个办法,但这办法有很强的技巧性
在Users表里用一个int的每个binary表示这个User所有的interests
在Interest表里用一个大数numeric(10,0)的每个binary表示所有10亿用户每个人是否
有该interest
这种方法需要在程序中用Bit manipulation实现更新操作
这种方法也不行,因为大数再大,也不能存下所有十亿用户的信息
【在 j******o 的大作中提到】 : 给你一个interest name,要求列出所有用户名,你就知道痛苦了。
| S*******C 发帖数: 822 | 9 再换一种方法
在Users表里用一个int的每个binary表示这个User所有的interests
每个interest创建一个表格记录下所有有该interest的user_id
这样两种查询都很快,就是要创建很多interest表格,这个怎么样
【在 j******o 的大作中提到】 : 给你一个interest name,要求列出所有用户名,你就知道痛苦了。
| S*******C 发帖数: 822 | | p***m 发帖数: 387 | 11 首先你用 FOREIGN KEY 会影响速度,从这个应用来看没有必要。
前面那位同学说的都全写进一个表里,每种爱好一个列,这非常不好,浪费大量空间,
也违背了关系数据库的原则。
用户可以(按任何一种有道理的方式比如地区、名字)partition,可以加快查询的速
度。
爱好可以考虑两种办法提高效率,其本质是一样的。一是你现有的设计,按爱好的不同
partition。还有一种办法,每个爱好或着一类爱好一个表(比如运动类表,艺术类表
)。
补充一句,我不是DBA,只是工作中要用到数据库,所以还是让真正的专业人士来回答
更有价值。
【在 S*******C 的大作中提到】 : 英文原文 : Design database for querying interest/likes of site users. : Assume that number of users is over 6 billion. : 下面的答案对吗? : create database usersByInterests; : use usersByInterests; : create table Users( : user_id numeric(10,0) PRIMARY KEY, : email VARCHAR(45) not NULL, : userPassword VARCHAR(45) not NULL,
| b********e 发帖数: 595 | 12 设计的和你的网名一样复杂,需要快速查询就在数据库里弄简单,又是foreign key,
又是constrain的,通通去掉.
user_id 10位unsigned好像是40亿, 放不下6 billion, user_id 设成bigint (12) 或
者更长一些,需要auto_increment, 兴趣简单的话就试试弄成set类型, 糙快猛的干法
就直接存json进去 | g*****g 发帖数: 34805 | 13 数据库设计的题但凡见到亿字,Cassandra通杀。
这就最简单两个Table, User table用username做key,指向所有Interest,Interest
table反过来即可。
为了避免hot spot还可以把interest table进一步划分,比如interest + A 指向这个
兴趣底下所有A打头的人名,这是个Scalable的设计。 | x*****n 发帖数: 195 | 14 楼主的意思是nosql吧。cassandra对应的是hadoop吧?我没用过。
这题用hbase就行,用空间换时间,题主去看HBase: The Definitive Guide,这题基本
跟书里贯穿几章节的例子差不多。
【在 g*****g 的大作中提到】 : 数据库设计的题但凡见到亿字,Cassandra通杀。 : 这就最简单两个Table, User table用username做key,指向所有Interest,Interest : table反过来即可。 : 为了避免hot spot还可以把interest table进一步划分,比如interest + A 指向这个 : 兴趣底下所有A打头的人名,这是个Scalable的设计。
|
|