数据库的高级设计

一.标准化

数据库的设计中,最小化数据冗余和数据库的效率之间存在一个折衷。

1.第一范式:

  • 定义所需要的数据项,将相关的数据项放置在一个表中。
  • 确保没有重复的数据组。(可以通过将数据划分到多个表中,来删除重复的数据)
  • 确保存在一个主键。

主键:记录的唯一标示符。可以添加一个新列,或者使用现有的一个或者多个列,只要这些列能够组合成一个唯一的主键。

2.第二范式:要求主键中的任意列没有局部相关性。

3.第三范式(可选项,依赖于环境):符合第二范式,所有非主键字段都依赖主键。

传递相关性。消除传递相关性——把具有传递相关性的数据项单独放在一个表中。

好处是:数据重复量降低;数据完整性,避免重复数据改变时,只更新了某些数据的危险。

不利因素:增加了复杂性并且降低了效率。

二.利用约束确保数据的有效性

 1.NOT NULL约束

Create table mytable(Column1 int not null, Column2 varchar(20));
alter table mytable
alter column column2 varchar(20) not null ;   --将一列更改为not null类型。这个更改能够成功的前提是,原数据表中没有null型的记录。对于其他的约束修改也是一样的,不能够和表中的已有数据冲突。

2.UNIQUE约束

 --一种添加unique约束的方式
Create table mytable(Column1 int not null unique, Column2 varchar(20) unique);  

--另一种添加unique约束的方式,在定义的列列举之后添加约束,可以为约束指定一个名称,并且可以使用SQL语句删除该约束.
--可以指定两个或者多个列的组合必须为唯一
Create table anothertable(
  Column1 int,
  Column2 varchar(20),
  Column3 varchar(12),
  CONSTRAINT MyUniqueConstraint UNIQUE(Column1,Column2),
  CONSTRAINT AnotherUniqueConstraint UNIQUE(Column1,Column3)  
  )  ;
Alter table anothertable
drop constraint MyUniqueConstraint;
Alter table anothertable
add CONSTRAINT MyUniqueConstraint UNIQUE(Column1,Column2);

3.CHECK约束

CREATE TABLE NamesAges(
   Name varchar(50),
   Age int CHECK(Age>=0)    --Age列的条件必须为true或者unknown
);

INSERT INTO NamesAges(Name,Age) Values('JIM',30);    --成功
INSERT INTO NamesAges(Name) Values('JIM');     --成功
INSERT INTO NamesAges(Name,Age) Values('JIM',-22);  --失败

delete from NamesAges where Age is null;  
Alter table NamesAges
alter column Age int not null;   

alter table NamesAges
add constraint Age check(age<=40);  --另一种方法添加check约束
CREATE TABLE Employee
(
      EmployeeName varchar(50),
      AvgMonthlyWage decimal(12,2),
      HourlyRate decimal(12,2),
      CONSTRAINT hourlyLess CHECK(AvgMonthlyWage>HourlyRate),  --如果希望CHECK条件子句包含表中的多个列,则需要在列末尾定义它
)

--或者使用alter table和add constraint
alter table Employee
add constraint hourlyLess CHECK(AvgMonthlyWage>HourlyRate);

4.主键和PRIMARY KEY约束

--主键提供了表之间的链接
--主键约束是UNIQUE和NOT NULL的组合
create table HolidayBookings
(
  CustomerId int primary key,  
  BookingId int NOT NULL,
  Destination varchar(50),
)

--组合主键
create table MoreHolidayBookings
(
  CustomerId int NOT NULL,  
  BookingId int NOT NULL,
  Destination varchar(50),
  CONSTRAINT booking_pk PRIMARY KEY(CustomerId,BookingId)  --同一个人不能同时借两本相同的数。一个人可以借多本书,相同的书号的数也可以被多人借。主键约束,不允许CustomerId,BookingId中的任何一个为null
);

--为现有表添加主键约束,前提条件是被设为主键的列已经被定义成了not null型
create table MoreHolidayBookings
(
  CustomerId int NOT NULL,  
  BookingId int NOT NULL,
  Destination varchar(50),
);
alter table MoreHolidayBookings
add constraint more_holiday_pk primary kay(CustomerId,BookingId) 

 5.外键约束

外键是访问另一个表的主键的列。

假设有2个表Location和Attenedance,在利用内部联接来查找数据时,查找Attenedance.LocationId=Location.LocationId的数据。当往Attenedance中插入了一个记录,其Attenedance.LocationId值在Location中无效的时候,破坏了这种联接性。

外键约束就可以保证这种联接性,即一个表中的一个列是引用另一个表中的记录行的方法。

alter table attendance add constraint location_fk foreign key(LocationId) references Location(LocationId);   --由一列组成的主键和外键
--当创建了外键约束后,如果往attendance中添加的记录,其LocationId在它所依赖的主键中无效,那么添加会出错

alter table SomeTable ADD CONSTRAINT sometable_fkl foreign key (employeename,employeeid,membershipid) references someprimarykeytable(employeename,employeeid,membershipid);  --主键和外键由3列组成

--也可以在创建一个表的时候就添加主键
create table attendence
(
     LocationId integer,
     MeetingDate date,
     MemberAttended char(1),
     MemberId integer,
     CONSTRAINT SomeTable_fk1 FOREIGN KEY (LocationId) REFERENCES Location(LocationId)
);

三.利用索引加速结果查询

CREATE INDEX index_name ON table_name (col1,col2);  --创建索引
select col1,col2 from table_name;    --添加了索引后,输出结果按升序排列。默认情况下,索引按升序排列。
DROP INDEX table_name.index_name;    --删除索引
select col1,col2 from table_name;     --删除索引后,输出结果不再按照顺序排列
create unique index index_name on table_name(col1 desc,col2);   --创建一个唯一的索引,按col1的降序排列然后按col2的升序排列
原文地址:https://www.cnblogs.com/wy1290939507/p/4506677.html