(在任何人问之前,这纯粹只是为了学习经验,仅此而已)
我正在尝试在PHP / MySQL中从头开始创建一个社交网络,但我很难想到它的最佳MySQL结构,目前我有:
这是一个存储所有用户信息的表:
fname varchar (300),
sname varchar (300),
pass varchar (400),
email varchar (300),
gender varchar (300),
dob varchar (200),
uid varchar (300),
PRIMARY KEY (id)
这是在用户注册时创建的,他们自己的个人表:
id int(20) NOT NULL auto_increment,
uid varchar (300),
photo_url varchar (400),
pfid varchar (300),
phototime datetime,
video_url varchar (400),
vfid varchar (300),
videotime datetime,
status longtext,
sid varchar (300),
statustime datetime,
blog longtext,
bid varchar (300),
blogtime datetime,
about_bio longtext,
about_current_job longtext,
about_secondary_school longtext,
about_primary_school longtext,
about_college longtext,
about_university longtext,
about_workemail longtext,
about_homeemail longtext,
about_phonenumber longtext,
about_relationshipstatus longtext,
about_relationshipwith longtext,
PRIMARY KEY (id)
)";
用于跟踪某人是否已登录的会话表:
id int(20) NOT NULL auto_increment,
sid varchar(300),
uid varchar(300),
PRIMARY KEY (id)
尚未建立关系,但我在想:
id int(20) NOT NULL auto_increment,
requestby varchar(200),
requestto varchar(200),
status varchar(200)
答案 0 :(得分:5)
嗯,肯定每个用户不应该有一个表。我认为更像这样的数据库结构可以很好地工作:
CREATE TABLE users (
userID INT NOT NULL AUTO_INCREMENT,
firstName VARCHAR(30),
lastName VARCHAR(30),
password CHAR(32), -- should be encrypted, CHAR is better if the field is always the same length
email VARCHAR(64) NOT NULL, -- not null if this is what you will use as a "username"
PRIMARY KEY (userID)
);
CREATE TABLE personalInfo (
userID INT NOT NULL,
gender ENUM ('MALE', 'FEMALE'),
dateOfBirth DATE,
phoneNumber VARCHAR(15),
personalEmail VARCHAR(64), -- may or may not be the same as the email field in the "users" table
workEmail VARCHAR(64),
bio TEXT,
FOREIGN KEY (userID) REFERENCES users (userID)
);
/* this table is not specific to any single user. It is just a list of jobs that have been created */
CREATE TABLE jobs (
jobID INT NOT NULL AUTO_INCREMENT,
company VARCHAR(100),
title VARCHAR(100),
description TEXT,
PRIMARY KEY (jobID)
);
/* the workInfo table will hold one entry per user per job. So if a user has held five jobs,
there will be five rows with that userID in this table, each with a different jobID, which
refers to an entry in the "jobs" table above. */
CREATE TABLE workInfo (
userID INT NOT NULL,
jobID INT NOT NULL,
startDate DATE,
endDate DATE, -- can set this to null if it's the user's current job
FOREIGN KEY (userID) REFERENCES users (userID),
FOREIGN KEY (jobID) REFERENCES jobs (jobID)
);
CREATE TABLE schools (
schoolID INT NOT NULL AUTO_INCREMENT,
schoolName VARCHAR(100),
-- any other information you want to provide about the school (city, address, phone, etc)
PRIMARY KEY (schoolID)
);
CREATE TABLE schoolPrograms (
programID INT NOT NULL AUTO_INCREMENT,
programName VARCHAR(100),
-- any other information you want to provide about the program (department, teachers, etc)
PRIMARY KEY (programID)
);
CREATE TABLE educationInfo (
userID INT NOT NULL,
schoolID INT,
programID INT,
startDate DATE,
endDate DATE,
FOREIGN KEY (userID) REFERENCES users (userID),
FOREIGN KEY (schoolID) REFERENCES schools (schoolID),
FOREIGN KEY (programID) REFERENCES schoolPrograms (programID)
);
CREATE TABLE relationships (
userID INT NOT NULL,
userID2 INT, -- allowed to be null if the user is single or does not specify who they are in a relationship with
status ENUM ('SINGLE', 'IN A RELATIONSHIP', 'MARRIED', 'IT''S COMPLICATED' /* etc */),
FOREIGN KEY (userID) REFERENCES users (userID)
);
/* each photo is created here. This way, when a user wants to share a photo,
we don't have to duplicate each column. We just create another row in
the "userPhotos" table below that) REFERENCES the same photoID. */
CREATE TABLE photos (
photoID INT NOT NULL AUTO_INCREMENT,
url VARCHAR(200),
caption VARCHAR(200),
dateOfUpload TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (photoID)
);
CREATE TABLE userPhotos (
userID INT NOT NULL,
photoID INT NOT NULL,
FOREIGN KEY (userID) REFERENCES users (userID),
FOREIGN KEY (photoID) REFERENCES photos (photoID)
);
/* vidoes, handled exactly the same as photos */
CREATE TABLE videos (
videoID INT NOT NULL AUTO_INCREMENT,
url VARCHAR(200),
caption VARCHAR(200),
dateOfUpload TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (videoID)
);
CREATE TABLE userVideos (
userID INT NOT NULL,
videoID INT NOT NULL,
FOREIGN KEY (userID) REFERENCES users (userID),
FOREIGN KEY (videoID) REFERENCES videos (videoID)
);
CREATE TABLE status (
userID INT NOT NULL,
status TEXT,
FOREIGN KEY (userID) REFERENCES users (userID)
);
答案 1 :(得分:0)
不要在所有这些字段中使用大型varchars。如果您保留一个解释每个值的查找表(或代码中的列表),友谊状态可以只是一个int。
如果用户表具有自动递增ID,则可以将该ID用于外键关系。即使你不希望UID是一个整数,你仍然可以使它成为一个GUID或其它比varchar小得多的东西。
这些表只指定一个配置文件,也许是一个关系,但还有更多。甚至像Twitter这样简单的东西也有一个推文列表,列表,列表中的帐户,跟随列表的用户,直接消息(尽管理论上这些可能与Tweets在同一个表中),链接的应用程序,阻止的用户等等等等。
所以我认为首先,您应该考虑一下您的社交网络应该是什么,它应该是什么样的,应该具有哪些功能。然后,将其剥离到最基本的功能。然后,再把它剥掉一点,你还在想太大了。 ;) 当你明白你的最低愿望是什么时,你可能会更清楚你需要什么样的桌子。
不要忘记添加约束和索引!
请注意,在实践中,Twitter,Facebook和其他大型网络根本不使用MySQL,但要练习,MySQL就可以了。