数据库实验总结

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库实验总结相关的知识,希望对你有一定的参考价值。

参考技术A

  数据库实验总结【一】

  试验内容

  1、 数据表的建立

  基本表《简单的》带有主键

  带有外码约束的(外码来自其他表或者本表)

  2、 数据表的修改

  添加删除列

  修改列属性类型

  添加删除约束(约束名)

  元组的添加,修改,删除

  删除数据表

  试验过程

  1、create table student

  (

  sno char(9) primary key , /*sno是主码 列级完整性约束条件*/

  sname char(20) unique, /*sname取唯一值*/

  ssex char(2),

  sage smallint, /*类型为smallint*/

  sdept char(20) /*所在系*/

  );

  create table course

  (

  cno char(4) primary key, /*列级完整性约束条件,cno是主码*/

  cname char(40),

  cpno char(4), /*cpno的含义是先行课*/

  ccredit smallint,

  foreign key (cpno) references course(cno)

  /*表级完整性约束条件,cpno是外码,被参照表是course,被参照列是cno*/

  );

  create table sc

  (

  sno char(9),

  cno char(4),

  grade smallint,

  primary key (sno,cno),

  /*主码有两个属性构成,必须作为表级完整性进行定义*/

  foreign key (sno) references student(sno),

  /*表级完整性约束条件,sno是外码,被参照表是student*/

  foreign key (cno) references course(cno),

  /*表级完整性约束条件,cno是外码,被参照表示course*/

  );

  例1、create table s

  (

  cno varchar(3), /*变长的字符串,输入2个字符就是两个字符不会补空格*/

  sname varchar(20),

  status int,

  city varchar(20),

  constraint pk_sno primary key(sno), /*约束条件的名字为pk_sno*/

  );

  create table p

  (

  pno varchar(3),

  pname varchar(20),

  color varchar(3),

  weight int,

  constraint pk_pno primary key (pno), /*约束条件的名字是pk_pno*/

  );

  create table j

  (

  jno varchar(3),

  jname varchar(20),

  city varchar(20),

  constraint pk_jno primary key(jno) /*约束条件的名字为pk_jno*/

  );

  例2、create table spj

  (

  sno varchar(3), /*第一个表中的主码*/

  pno varchar(3),

  jno varchar(3),

  qty int, /*数量*/

  constraint pk_spj primary key(sno,pno,jno), /*主码由3个属性组成*/

  foreign key(sno) references s(sno),

  /*表级完整性约束条件,sno是外码,被参照表是s*/

  foreign key(pno) references p(pno),

  /*表级完整性约束条件,pno是外码,被参照表是p*/

  foreign key(jno) references j(jno),

  /*表级完整性约束条件,jno是外码,被参照表是j*/

  );

  2、数据表的更改

  在s表中添加一个concat 列

  alter table s add concat varchar(20)

  在s表中删除concat 列

  alter table s drop column concat

  更改s表 concat列的属性 把长度由20改为30

  alter table s alter column concat varchar(30)

  联系方式 名字为concat 修改属性为唯一的 属性名为con_concat

  alter table s add constraint con_concat unique(concat)

  删除约束关系con_concat

  alter table s drop constraint con_concat

  /*插入一个元组*/

  insert into s valus(‘s1’,’精益’,20,’天津’) /*20不能写成’20’*/

  试验中的问题的排除与总结:

  1、在创建spj时

  有三个实体所以从3个实体中取主码,还有一个数量属性也要写上

  主码由那3个主码确定

  2、更改一个数据库中数据表时一定要先使该数据库处于正在使用状态

  3、constraint

  是可选关键字,表示 primary key、not null、unique、foreign key 或 check 约束定义的开始。约束是特殊属性,用于强制数据完整性并可以为表及其列创建索引。

  4、--go可以不加但是要注意顺序 注:go --注释 提示错误

  5、注意添加一个空元素用 null

  附 sql备份

  --创建一个数据库 student

  create database student

  go

  --在数据库student中创建表student course sc 注意顺序

  use student

  ----------------------------------------------------------------

  create table student

  (

  sno char(9) primary key, /*sno是主码 列级完整性约束条件*/

  sname char(10) unique, /*sname取唯一值*/

  ssex char(2),

  sage smallint, /*类型为smallint*/

  sdept char(20) /*所在系*/

  ); /*;要加*/

  -----------

  数据库实验总结【二】

  我在sql server 索引基础知识系列中,第一篇就讲了记录数据的基本格式。那里主要讲解的是,数据库的最小读存单元:数据页。一个数据页是8k大小。

  对于数据库来说,它不会每次有一个数据页变化后,就存到硬盘。而是变化达到一定数量级后才会作这个操作。 这时候,数据库并不是以数据页来作为操作单元,而是以64k的数据(8个数据页,一个区)作为操作单元。

  区是管理空间的基本单位。一个区是八个物理上连续的页(即 64 kb)。这意味着 sql server 数据库中每 mb 有 16 个区。

  为了使空间分配更有效,sql server 不会将所有区分配给包含少量数据的表。sql server 有两种类型的区:

  统一区,由单个对象所有。区中的所有 8 页只能由所属对象使用。

  混合区,最多可由八个对象共享。区中八页的每页可由不同的对象所有。

  通常从混合区向新表或索引分配页。当表或索引增长到 8 页时,将变成使用统一区进行后续分配。如果对现有表创建索引,并且该表包含的行足以在索引中生成 8 页,则对该索引的所有分配都使用统一区进行。

  为何会这样呢?

  其实很简单:

  读或写 8kb 的时间与读或写 64 kb的时间几乎相同。

  在 8 kb 到 64 kb 范围之内,单个磁盘 i/o 传输操作所花的时间主要是磁盘取数臂和读/写磁头运动的时间。

  因此,从数学上来讲,当需要传输 64 kb 以上的 sql 数据时,

  尽可能地执行 64 kb 磁盘传输是有益的,即分成数个64k的操作。

  因为 64 kb 传输基本上与 8 kb 传输一样快,而每次传输的 sql server 数据是 8 kb 传输的 8 倍。

  我们通过一个实例来看 有and 操作符时候的最常见的一种情况。我们有下面一个表,

  create table [dbo].[member]( [member_no] [dbo].[numeric_id] identity(1,1) not null, [lastname] [dbo].[shortstring] not null, [firstname] [dbo].[shortstring] not null, [middleinitial] [dbo].[letter] null, [street] [dbo].[shortstring] not null, [city] [dbo].[shortstring] not null, [state_prov] [dbo].[statecode] not null, [country] [dbo].[countrycode] not null, [mail_code] [dbo].[mailcode] not null, [phone_no] [dbo].[phonenumber] null, [photograph] [image] null, [issue_dt] [datetime] not null default (getdate()), [expr_dt] [datetime] not null default (dateadd(year,1,getdate())), [region_no] [dbo].[numeric_id] not null, [corp_no] [dbo].[numeric_id] null, [prev_balance] [money] null default (0), [curr_balance] [money] null default (0), [member_code] [dbo].[status_code] not null default (\' \'))

  这个表具备下面的四个索引:

  索引名 细节 索引的列

  member_corporation_link nonclustered located on primary corp_no

  member_ident clustered, unique, primary key located on primary member_no

  member_region_link nonclustered located on primary region_no

  memberfirstname nonclustered located on primary firstname

  当我们执行下面的sql查询时候,

  select m.member_no, m.firstname, m.region_nofrom dbo.member as mwhere m.firstname like \'k%\' and m.region_no > 6 and m.member_no < 5000go

  sql server 会根据索引方式,优化成下面方式来执行。

  select a.member_no,a.firstname,b.region_nofrom(select m.member_no, m.firstname from dbo.member as m where m.firstname like \'k%\' and m.member_no < 5000) a , -- 这个查询可以直接使用 memberfirstname 非聚集索引,而且这个非聚集索引覆盖了所有查询列-- 实际执行时,只需要 逻辑读取 3 次

  (select m.member_no, m.region_no from dbo.member as mwhere m.region_no > 6) b

  -- 这个查询可以直接使用 member_region_link 非聚集索引,而且这个非聚集索引覆盖了所有查询列-- 实际执行时,只需要 逻辑读取 10 次

  where a.member_no = b.member_no

  不信,你可以看这两个sql 的执行计划,以及逻辑读信息,都是一样的。

  其实上面的sql,如果优化成下面的方式,实际的逻辑读消耗也是一样的。为何sql server 不会优化成下面的方式。是因为 and 操作符优化的另外一个原则。

  1/26 的数据和 1/6 的数据找交集的速度要比 1/52 的数据和 1/3 的数据找交集速度要慢。

  select a.member_no,a.firstname,b.region_nofrom(select m.member_no, m.firstname from dbo.member as mwhere m.firstname like \'k%\' -- 1/26 数据) a,

  (select m.member_no, m.region_no from dbo.member as mwhere m.region_no > 6 and m.member_no < 5000-- 1/3 * 1/ 2 数据) bwhere a.member_no = b.member_no

  当然,我们要学习sql 如何优化的话,就会用到查询语句中的一个功能,指定查询使用哪个索引来进行。

  比如下面的查询语句

  select m.member_no, m.firstname, m.region_nofrom dbo.member as m with (index (0))where m.firstname like \'k%\' and m.region_no > 6 and m.member_no < 5000go

  select m.member_no, m.firstname, m.region_nofrom dbo.member as m with (index (1))where m.firstname like \'k%\' and m.region_no > 6 and m.member_no < 5000goselect m.member_no, m.firstname, m.region_nofrom dbo.member as m with (index (membercovering3))where m.firstname like \'k%\' and m.region_no > 6 and m.member_no < 5000goselect m.member_no, m.firstname, m.region_nofrom dbo.member as m with (index (memberfirstname, member_region_link))where m.firstname like \'k%\' and m.region_no > 6 and m.member_no < 5000go

  这里 index 计算符可以是 0 ,1, 指定的一个或者多个索引名字。对于 0 ,1 的意义如下:

  如果存在聚集索引,则 index(0) 强制执行聚集索引扫描,index(1) 强制执行聚集索引扫描或查找(使用性能最高的一种)。

  如果不存在聚集索引,则 index(0) 强制执行表扫描,index(1) 被解释为错误。

  总结知识点:

  简单来说,我们可以这么理解:sql server 对于每一条查询语句。会根据实际索引情况(sysindexes 系统表中存储这些信息),分析每种组合可能的成本。然后选择它认为成本最小的一种。作为它实际执行的计划。

  成本代价计算的一个主要组成部分是逻辑i/o的数量,特别是对于单表的查询。

  and 操作要满足所有条件,这样,经常会要求对几个数据集作交集。数据集越小,数据集的交集计算越节省成本。

  的项目中,竟然出现了滥用聚集索引的问题。看来没有培训最最基础的索引的意义,代价,使用场景,是一个非常大的失误。这篇博客就是从这个角度来罗列索引的基础知识。

  使用索引的意义

  索引在数据库中的作用类似于目录在书籍中的作用,用来提高查找信息的速度。

  使用索引查找数据,无需对整表进行扫描,可以快速找到所需数据。

  使用索引的代价

  索引需要占用数据表以外的物理存储空间。

  创建索引和维护索引要花费一定的时间。

  当对表进行更新操作时,索引需要被重建,这样降低了数据的维护速度。

  创建索引的列

  主键

  外键或在表联接操作中经常用到的列

  在经常查询的字段上最好建立索引

  不创建索引的列

  很少在查询中被引用

  包含较少的惟一值

  定义为 text、ntext 或者 image 数据类型的列

  heaps是staging data的很好选择,当它没有任何index时

  excellent for high performance data loading (parallel bulk load and parallel index creation after load)

  excellent as a partition to a partitioned view or a partitioned table

  聚集索引提高性能的方法,在前面几篇博客中分别提到过,下面只是一个简单的大纲,细节请参看前面几篇博客。

  何时创建聚集索引?

  clustered index会提高大多数table的性能,尤其是当它满足以下条件时:

  独特, 狭窄, 静止: 最重要的条件

  持续增长的,最好是只向上增加。例如:

  identity

  date, identity

  guid (only when using newsequentialid() function)

  聚集索引唯一性(独特型的问题)

  由于聚集索引的b+树结构的叶子节点必须指向具体数据。如果你要建立聚集索引的列不唯一,并且你指定的创建的聚集索引是非唯一的聚集索引,则会有以下情况:

  如果未使用 unique 属性创建聚集索引,数据库引擎 将向表自动添加一个四字节 uniqueifier 列。必要时,数据库引擎 将向行自动添加一个 uniqueifier 值,使每个键唯一。此列和列值供内部使用,用户不能查看或访问。

AOV拓扑排序实验总结-1

AOV拓扑排序实验总结-1
 
实验数据:
1、实验输入数据在input.txt文件中
2、对于n是指有顶点n个,数据的结束标志是一行0 0。
 
实验目的:获取优秀的AOV排序算法模板
 
数据结构安排:
1、队列:负责记录入度为0且没有排序的AOV顶点
2、邻接表结点:邻接表结点采用自定义的复合结构,保存顶点信息、边表头指针。
3、邻接表边表:采取链表的形式存储数据
4、邻接表的数据类型是相同的,只是在概念上使得结点独特的保存了当前起始顶点
5、按照vertex的编号独立的使用一个数组indegree保存入度,一定程度的节省了空间
 
实验内容:1、算法模板的设计 2、算法类的设计或头文件封装的尝试
 
AOV算法模板要求:
1、假定AOV排序成立
2、vertex本身可以按照编号进行命名
 
构建的邻接表展现:
代码如下:
 1 for(int i=0;i<n;i++)
 2     {
 3         printf("vertex %d indegree %d points to:",aim[i].vertex,indegree[i]);
 4         point* temp=&aim[i];
 5         while(temp->next!=NULL)
 6         {
 7             temp=temp->next;
 8             printf("%d ",temp->vertex);
 9         }
10         printf("
");
11     }

 

展示情况:
vertex 0 indegree 0 points to:8 2
vertex 1 indegree 0 points to:2 4
vertex 2 indegree 2 points to:3
vertex 3 indegree 2 points to:5 7 9 10
vertex 4 indegree 1 points to:6
vertex 5 indegree 1 points to:
vertex 6 indegree 1 points to:10
vertex 7 indegree 1 points to:
vertex 8 indegree 1 points to:9 3
vertex 9 indegree 2 points to:
vertex 10 indegree 2 points to:
总体模板运行结果:
  0  1  8  2  4  3  6  5  7  9 10
运行正常
 
实验代码:
 1 //算法模板的设计
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<malloc.h>
 5 #include<cstring>
 6 #include<queue>
 7 #include<algorithm>
 8 using namespace std;
 9 const int maxn = 30;
10 struct point
11 {
12     int vertex;//顶点
13     point* next;
14 };
15 
16 int indegree[maxn];
17 point aim[maxn];
18 int n;
19 
20 int readin()
21 {
22     scanf("%d",&n);
23     memset(indegree,0,sizeof(int)*n);
24     for(int i=0;i<n;i++)
25     {
26         aim[i].next=NULL;
27         aim[i].vertex=i;
28     }
29     //初始化
30     int a,b;
31     while(scanf("%d%d",&a,&b))
32     {//a->b
33         if(a==0&&b==0)break;
34         indegree[b]++;//入度加1
35         point* temp=&aim[a];
36         while(temp->next!=NULL)temp=temp->next;
37         //找到存有指向结点链表的末端
38         temp->next=(point*)malloc(sizeof(point));
39         temp=temp->next;//进入新的point点
40         temp->vertex=b;//a->b
41         temp->next=NULL;
42     }//完成邻接表的构建
43     return 0;
44 }
45 
46 queue<int> psd;
47 int topo_sort(int* ans)
48 {
49     bool ok[maxn];
50     memset(ok,false,sizeof(ok));
51     int cur=0;
52     int num=n;
53     while(1)
54     {
55         if(num)
56         {
57             for(int i=0;i<n;i++)
58             {
59                 if(ok[i])continue;
60                 if(indegree[i]==0)
61                 {
62                     psd.push(i);
63                     ok[i]=true;
64                     num--;
65                 }
66             }//检查所有入度0的顶点并入队,留下入队标记
67         }
68         if(psd.empty())break;//队列为空则排序结束
69         int p=psd.front();psd.pop();
70         point* temp=&aim[p];
71         ans[cur++]=p;//也可以写成ans[cur++]=aim[i].vertex;
72         //提出结点并排序
73         while(temp->next!=NULL)
74         {
75             temp=temp->next;
76             indegree[temp->vertex]--;
77         }//去掉相关有向边
78     }
79     return 0;
80 }
81 
82 int ans[maxn];
83 int main()
84 {
85     //freopen("input.txt","r",stdin);
86     //freopen("ans.txt","w",stdout);
87     readin();
88     topo_sort(ans);
89     for(int i=0;i<n;i++)
90     {
91         printf("%3d",ans[i]);
92     }
93     printf("
");
94     return 0;
95 }

 

以上是关于数据库实验总结的主要内容,如果未能解决你的问题,请参考以下文章

java实验报告总结

20172304 《程序设计与数据结构》实验三总结报告

AOV拓扑排序实验总结-1

实验五:实验结论和实验总结

实验九——基本数据类型存储及应用总结

实验九——基本数据类型存储及应用总结