关系数据库规范化问题

时间:2014-01-29 00:19:01

标签: sql database-design

我的网站是求职网站。有三种类型的用户:UserEmployeeAdmin

  • User可以搜索并申请工作,
  • Employee可以发布作业,浏览器恢复,
  • Admin是管理网站。

以下是我定义的所有表格。

-- Users table, users = jobseekers, containing jobseekers info  
DROP TABLE IF EXISTS users;
CREATE TABLE users (
  user_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  first_name VARCHAR(20) NOT NULL,
  last_name VARCHAR(40) NOT NULL,
  email VARCHAR(80) NOT NULL,
  pass CHAR(60) NOT NULL,
  user_phone VARCHAR(11) NOT NULL,
  user_address VARCHAR(250) NOT NULL,
  active CHAR(32) NULL,
  last_login_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
                                     ON UPDATE CURRENT_TIMESTAMP,
  last_login_ip VARCHAR(15) NOT NULL,
  registration_time DATETIME NOT NULL,
  registration_ip VARCHAR(15) NOT NULL,
  PRIMARY KEY (user_id),
  UNIQUE KEY (email),
  INDEX login (email, pass)
) ENGINE = INNODB;


-- Employers table, containing employers info
DROP TABLE IF EXISTS employers;
CREATE TABLE employers (
  employer_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  first_name VARCHAR(20) NOT NULL,
  last_name VARCHAR(40) NOT NULL,
  company_name VARCHAR(80) NOT NULL,
  email VARCHAR(80) NOT NULL,
  pass CHAR(40) NOT NULL,
  employer_phone VARCHAR(11) NOT NULL,
  employer_mobile VARCHAR(11),
  employer_address VARCHAR(250) NOT NULL,
  active CHAR(32) NULL,
  last_login_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
                                     ON UPDATE CURRENT_TIMESTAMP,
  last_login_ip VARCHAR(15) NOT NULL,
  registration_time DATETIME NOT NULL,
  registration_ip VARCHAR(15) NOT NULL,
  PRIMARY KEY (employer_id),
  UNIQUE KEY (email),
  INDEX login (email, pass)
) ENGINE = INNODB;


-- Administrators table, containing site administrators info
-- Note: move created_time after last_login_time, otherwise SQL error #1293
DROP TABLE IF EXISTS administrators;
CREATE TABLE administrators (
   admin_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
   first_name VARCHAR(20) NOT NULL,
   last_name VARCHAR(40) NOT NULL,
   email VARCHAR(80) NOT NULL,
   pass CHAR(40) NOT NULL,
   last_login_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
                                     ON UPDATE CURRENT_TIMESTAMP,
   last_login_ip VARCHAR(15) NOT NULL,
   created_time DATETIME NOT NULL,
   PRIMARY KEY (admin_id)
) ENGINE = INNODB;


-- CVs table, containing CV info
DROP TABLE IF EXISTS cvs;
CREATE TABLE cvs (
   cv_id INT(10) UNSIGNED NOT NULL auto_increment,
   cv_name VARCHAR(60) NOT NULL,
   user_id INT UNSIGNED NOT NULL,
   description VARCHAR(80),  
   PRIMARY KEY (cv_id)
) ENGINE = INNODB;


-- Jobs table, containing job information
-- Note: must use MYISAM to support Fulltext search
DROP TABLE IF EXISTS jobs;
CREATE TABLE jobs (
   job_id INT(10) UNSIGNED NOT NULL auto_increment,
   job_title VARCHAR(30) NOT NULL,
   employer_id INT UNSIGNED NOT NULL,
   company_name VARCHAR(80) NOT NULL,
   description TEXT NOT NULL,
   town VARCHAR(30) NOT NULL,
   county VARCHAR(30) NOT NULL,
   contact_name VARCHAR(40) NOT NULL,
   contact_phone VARCHAR(11) NOT NULL,
   contact_email VARCHAR(80) NOT NULL,
   salary SMALLINT(5) UNSIGNED NOT NULL,
   confirm TINYINT(1) UNSIGNED NOT NULL default 0,
   posted_time TIMESTAMP NOT NULL,
   deadline INT(10) UNSIGNED NOT NULL,
   job_status SET('open', 'closed') NOT NULL,  
   employer_paid SET('yes', 'no') NOT NULL,
   PRIMARY KEY (job_id),
   FULLTEXT (job_title, description)
) ENGINE = MYISAM;


-- Jobs users applied
DROP TABLE IF EXISTS jobs_applied;
CREATE TABLE jobs_applied (
   jobs_applied_id INT(10) UNSIGNED NOT NULL auto_increment,
   user_id INT UNSIGNED NOT NULL,
   cv_id INT(10) UNSIGNED NOT NULL,
   cv_name VARCHAR(60) NOT NULL,
   job_id INT(10) unsigned NOT NULL,
   job_title VARCHAR(30) NOT NULL,
   company_id INT(10) unsigned NOT NULL,
   company_name VARCHAR(80) NOT NULL,
   applied_time TIMESTAMP NOT NULL,
   PRIMARY KEY (jobs_applied_id)
) ENGINE = INNODB;


-- Reports table, containing info to produce site reports
DROP TABLE IF EXISTS reports;
CREATE TABLE reports (
   report_id INT(10) UNSIGNED NOT NULL auto_increment,
   user_id INT UNSIGNED NOT NULL,
   employer_id INT UNSIGNED NOT NULL,
   job_id INT(10) unsigned NOT NULL,
   job_title VARCHAR(30) NOT NULL,
   job_posttime TIMESTAMP NOT NULL,
   content VARCHAR(250) NOT NULL,
   report_time INT(10) UNSIGNED NOT NULL,
   PRIMARY KEY (report_id)
) ENGINE = INNODB;

有些人说我设计的表格正是我在关系数据库中不能做的,因为它们充满了重复。我不明白。有人请看看我的设计,并指出设计错误?

2 个答案:

答案 0 :(得分:1)

向我跳出的最大的问题(尽管有一些)是雇主和管理员字段的一半实际上只是用户/授权管理的一部分。保持“搜索者”和“雇主”和“管理员”的概念是分开的(单独的表格很好,实际上有助于FK关系),但应该有一个统一的“用户/帐户”关系。

例如,想象三个“角色区分”表。用户可以通过DRI与零或全部三者相关联(SQL本身不支持分布式FK),因此应该制定业务规则以确保正确的关联 - 但为什么雇主也不能成为搜索者?

这些表格可以包含与特定角色相关的其他信息(搜索者,雇主,管理员)。保持单独的表(而不仅仅是一个有区别的角色列)的好处是;

  1. 可根据需要将其他列添加到精炼类型中;
  2. 可以沿role_id建立FK,而不需要两部分(user_id,角色)。
  3. Seekers (people looking for jobs)
    ---
    seeker_id (PK)
    user_id (FK Users, not null)
    
    Employers
    ---
    employer_id (PK)
    user_id (FK Users, not null)
    
    Administrators
    ---
    admin_id (PK)
    user_id (FK Users, not null)
    
    Users/Accounts
    ---
    - All the data that relates to login/authorization information such as username
    - and password salt/hash, account contact e-mail, etc.
    - You probably want to separate the authentication such as login/auth information
    - and additional details, such as "last login from" or "registered from", etc.
    

    大多数“CMS”系统已经具备了身份验证和授权方案。


    应该规范化的其他事情(但是比我上面讨论的重复要少得多)是“联系信息”和“公司/地点”。将“工作”与“工作列表”分开也可能是值得的。此外,似乎有些字段只是简单地重复:

    company_id INT(10) unsigned NOT NULL,
    company_name VARCHAR(80) NOT NULL,
    

    由于已经的关系具有FK / Join的company_id,因此company_name列只是重复数据,应该被删除。

答案 1 :(得分:0)

您需要规范化数据库架构/设计,以避免存储重复数据。

请参阅有关使用示例进行规范化的文章:Description of the database normalization basics

在您的特定情况下,您应该将CompanyContactJobLocationJobTypeJobIndustry等分离到自己的表格中并使用关系链接他们。