用于社交网络的MySQL结构

时间:2012-03-29 18:07:52

标签: php mysql social

(在任何人问之前,这纯粹只是为了学习经验,仅此而已)

我正在尝试在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)

2 个答案:

答案 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就可以了。