MySQL Structure для социальной сети - PullRequest
2 голосов
/ 29 марта 2012

(Прежде чем кто-то спросит, это просто для обучения, не более)

Я экспериментирую, создавая социальную сеть с нуля в 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 ]

5 голосов
/ 29 марта 2012

Ну, у вас определенно не должно быть одной таблицы на пользователя.Я думаю, что структура базы данных, подобная этой, будет работать очень хорошо:

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)
);
0 голосов
/ 29 марта 2012

Не используйте большие поля для всех этих полей. Статус дружбы может быть просто int, если вы храните справочную таблицу (или список в вашем коде), которая объясняет каждое значение.

Если у пользовательской таблицы есть идентификатор с автоматическим приращением, вы можете использовать этот идентификатор для связей с внешним ключом. Даже если вы не хотите, чтобы UID был целым числом, вы все равно можете сделать его GUID или чем-то еще, намного меньшим, чем varchar.

В этих таблицах указывается только профиль и, возможно, связь, но есть гораздо больше. Даже в таких простых вещах, как Twitter, есть таблица твитов, списки, учетные записи для размещения в списке, пользователи, которые следуют за списком, прямые сообщения (хотя теоретически они могут быть в той же таблице, что и твиты), связанные приложения, заблокированные пользователи и многое другое. и многое другое.

Так что я думаю, прежде всего, вы должны подумать о том, какой должна быть ваша социальная сеть, как она должна выглядеть, какими функциями она должна обладать. Затем разделите это до наиболее важных функций. Тогда, разденьте это немного больше, Вы все еще думаете слишком большой. ;) Когда вы поймете, каково ваше минимальное желание, вам, вероятно, будет гораздо яснее, какой стол вам понадобится.

Не забудьте добавить ограничения и индексы!

Обратите внимание, что на практике Twitter, Facebook и другие крупные сети вообще не используют MySQL, но на практике с MySQL все в порядке.

...