数据库的高级设计

一.标准化

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

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的升序排列

 

你可能感兴趣的:(数据库)