java Web知识点--数据库(3)

介绍一下SQL Server的全文索引?

全文索引可以对存储在SQL Server数据库中的文本数据执行快速检索功能。同LIKE谓词不同,全文索引只对字符模式进行操作,对字和语句执行搜索功能。全文索引对于查询非结构化数据非常有效。一般情况下,可以对char、varchar和nvarchar数据类型的列创建全文索引,同时,还可以对二进制格式的列创建索引,如image和varbinary数据类型列。对于这些二进制数据,无法使用LIKE谓词。

为了对表创建全文索引,表必须包含单个、唯一、非空列。当执行全文检索的时候,SQL Server搜索引擎返回匹配搜索条件的行的键值。一般情况,使用sql server中的全文索引,经过大体4个步骤:

l         安装全文索引服务;

l         为数据表建立全文索引目录;

l         使全文索引与数据表内容同步;

l         使用全文索引进行查询。

SQL Server里面什么样的视图才能创建索引?

在为视图创建索引前,视图本身必须满足以下条件:

l         视图以及视图中引用的所有表都必须在同一数据库中,并具有同一个所有者。

l         索引视图无需包含要供优化器使用的查询中引用的所有表。

l         必须先为视图创建唯一群集索引,然后才可以创建其它索引。

l         创建基表、视图和索引以及修改基表和视图中的数据时,必须正确设置某些 SET 选项(在本文档的后文中讨论)。另外,如果这些 SET 选项正确,查询优化器将不考虑索引视图。

l         视图必须使用架构绑定创建,视图中引用的任何用户定义的函数必须使用 SCHEMABINDING 选项创建。

l         另外,还要求有一定的磁盘空间来存放由索引视图定义的数据。

介绍一下SQL Server里面的索引视图?

复杂报表的场景经常会在数据仓储应用程序中遇到,它在查询过程中会对数据库服务器产生大量请求。当这些查询访问视图时,因为数据库将建立视图结果集所需的逻辑合并到从基本表数据建立完整查询结果集所需的逻辑中,所以性能将会下降。这一操作的开销可能会比较大,尤其当视图涉及到复杂的大量行处理–如大量数据聚合或多表联结时。因为结果集并不永久存放在数据库(标准视图)中,以后对该视图的访问可能导致在每次执行查询时建立结果集的代价。

SQL Server允许为视图创建独特的聚集索引,从而让访问此类视图的查询的性能得到极大地改善。在创建了这样一个索引后,视图将被执行,结果集将被存放在数据库中,存放的方式与带有聚集索引的表的存放方式相同。这就在数据库中有效地实现了查询结果。对于那些在FROM子句中不直接指定视图名的查询,SQL Server查询优化器将使用视图索引。现有查询将受益于从索引视图检索数据而无需重新编写程序原码的高效率。对于某些特定类型的视图,甚至可以获得指数级的性能改善。

如果在视图上创建索引,那么视图中的数据会被立即存储在数据库中,对索引视图进行修改,那么这些修改会立即反映到基础表中。同理,对基础表所进行的数据修改也会反映到索引视图那里。索引的惟一性大大提高了SQL Server 查找那些被修改的数据行。

维护索引视图比维护基础表的索引更为复杂。所以,如果认为值得以因数据修改而增加系统负担为代价来提高数据检索的速度,那么应该在视图上创建索引。

什么是唯一索引?

唯一索引可以确保索引列不包含重复的值。在多列唯一索引的情况下,该索引可以确保索引列中每个值组合都是唯一的。例如,如果在 last_name、first_name 和 middle_initial 列的组合上创建了唯一索引 full_name,则该表中任何两个人都不可以具有相同的全名。

聚集索引和非聚集索引都可以是唯一的。因此,只要列中的数据是唯一的,就可以在同一个表上创建一个唯一的聚集索引和多个唯一的非聚集索引。

只有当唯一性是数据本身的特征时,指定唯一索引才有意义。如果必须实施唯一性以确保数据的完整性,则应在列上创建 UNIQUE 或 PRIMARY KEY 约束,而不要创建唯一索引。例如,如果打算经常查询雇员表(主键为 emp_id)中的社会安全号码 (ssn) 列,并希望确保社会安全号码的唯一性,则在 ssn 列上创建 UNIQUE 约束。如果用户为一个以上的雇员输入了同一个社会安全号码,则会显示错误。

什么是聚集索引和非聚集索引?分布介绍一下

1)非聚集索引

非聚集索引与课本中的索引类似。数据存储在一个地方,索引存储在另一个地方,索引带有指针指向数据的存储位置。索引中的项目按索引键值的顺序存储,而表中的信息按另一种顺序存储(这可以由聚集索引规定)。如果在表中未创建聚集索引,则无法保证这些行具有任何特定的顺序。

典型的桌面数据库使用的是非聚集索引。在这类索引中,索引键值是有序的,而每个索引节点所指向的数据行是无序的。一个SQL Server表最多可以拥有255个非聚集索引。

非聚集索引与聚集索引一样有 B-树结构,但是有两个重大差别:

l         数据行不按非聚集索引键的顺序排序和存储。

l         非聚集索引的叶层不包含数据页。

相反,叶节点包含索引行。每个索引行包含非聚集键值以及一个或多个行定位器,这些行定位器指向有该键值的数据行(如果索引不唯一,则可能是多行)。非聚集索引可以在有聚集索引的表、堆集或索引视图上定义。在 SQL Server中,非聚集索引中的行定位器有两种形式:

l         如果表是堆集(没有聚集索引),行定位器就是指向行的指针。该指针用文件标识符 (ID)、页码和页上的行数生成。整个指针称为行 ID。

l         如果表是堆集(没有聚集索引),行定位器就是指向行的指针。该指针用文件标识符 (ID)、页码和页上的行数生成。整个指针称为行 ID。

由于非聚集索引将聚集索引键作为其行指针存储,因此使聚集索引键尽可能小很重要。如果表还有非聚集索引,请不要选择大的列作为聚集索引的键。

在创建非聚集索引之前,应先了解您的数据是如何被访问的。可考虑将非聚集索引用于:

l         包含大量非重复值的列,如姓氏和名字的组合(如果聚集索引用于其它列)。如果只有很少的非重复值,如只有 1 和 0,则大多数查询将不使用索引,因为此时表扫描通常更有效。

l         不返回大型结果集的查询。

l         返回精确匹配的查询的搜索条件(WHERE 子句)中经常使用的列。

l         经常需要联接和分组的决策支持系统应用程序。应在联接和分组操作中使用的列上创建多个非聚集索引,在任何外键列上创建一个聚集索引。

l         在特定的查询中覆盖一个表中的所有列。这将完全消除对表或聚集索引的访问。

2)聚集索引

聚集索引确定表中数据的物理顺序。聚集索引类似于电话簿,后者按姓氏排列数据。由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引。但该索引可以包含多个列(组合索引),就像电话簿按姓氏和名字进行组织一样。

聚集索引在系统数据库表sysindexes 内有一行,其 indid = 1。数据链内的页和其内的行按聚集索引键值排序。所有插入都在所插入行中的键值与排序顺序相匹配时执行。

SQL Server将索引组织为B-树。索引内的每一页包含一个页首,页首后面跟着索引行。每个索引行都包含一个键值以及一个指向较低级页或数据行的指针。索引的每个页称为索引节点。B-树的顶端节点称为根节点。索引的底层节点称为叶节点。每级索引中的页链接在双向链接列表中。在聚集索引内数据页组成叶节点。根和叶之间的任何索引级统称为中间级。

对于聚集索引,sysindexes.root 指向它的顶端。SQL Server 沿着聚集索引浏览以找到聚集索引键对应的行。为找到键的范围,SQL Server 浏览索引以找到这个范围的起始键值,然后用向前或向后指针扫描数据页。为找到数据页链的首页,SQL Server 从索引的根节点开始沿最左边的指针进行扫描.

聚集索引对于那些经常要搜索范围值的列特别有效。使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻。例如,如果应用程序执行的一个查询经常检索某一日期范围内的记录,则使用聚集索引可以迅速找到包含开始日期的行,然后检索表中所有相邻的行,直到到达结束日期。这样有助于提高此类查询的性能。同样,如果对从表中检索的数据进行排序时经常要用到某一列,则可以将该表在该列上聚集(物理排序),避免每次查询该列时都进行排序,从而节省成本。

对于聚集索引,人们往往有一些错误的认识。其中,最常见的错误有:

l         聚集索引会降低insert操作的速度,因为必须要向后移动一半的数据来为新插入的行腾出空间。这种认识是错误的,因为可以利用填充因子控制填充的百分比,从而在索引页上为新插入的数据保留空间。如果索引页填满了,SQL Server将会进行页拆分,在这种情况下只有第一个页才会受到影响。

l         在使用标识列的主键上创建聚集索引是一种好的设计方法,它可以使对表的操作达到最快速度。这种认识是错误的,它浪费了创建其它更有效的聚集索引的机会。并且,使用这种方法会把每个新插入的记录行都存储到表尾部的同一个的数据页中,这将导致数据库的热点和锁争用。笔者曾经见过采用这种方法设计的数据库,对于每一个新订单,客户服务人员都不得不等待数分钟来加以确认。

l         聚集索引是具有魔力的。如果哪个查询的速度不够快,那么就在该列上创建聚集索引,对于表的操作速度一定会得到提高。这种认识也是错误的,聚集索引只是比非聚集索引稍稍快了那么一点点。因为在每个表上只能创建一个聚集索引,所以它也是一种宝贵的性能资源,只有在那些经常作为条件查询一组记录行的列上才应该建立聚集索引。

在创建聚集索引之前,应先了解数据是如何被访问的。可考虑将聚集索引用于:

l         包含大量非重复值的列。

l         使用下列运算符返回一个范围值的查询:BETWEEN、>、>=、< 和 <=。

l         被连续访问的列。

l         返回大型结果集的查询。

l         经常被使用联接或 GROUP BY 子句的查询访问的列;一般来说,这些是外键列。对 ORDER BY 或 GROUP BY 子句中指定的列进行索引,可以使 SQL Server 不必对数据进行排序,因为这些行已经排序。这样可以提高查询性能。

l         OLTP 类型的应用程序,这些程序要求进行非常快速的单行查找(一般通过主键)。应在主键上创建聚集索引。

注意,聚集索引不适用于:

l         频繁更改的列,这将导致整行移动(因为 SQL Server 必须按物理顺序保留行中的数据值)。这一点要特别注意,因为在大数据量事务处理系统中数据是易失的。

l         宽键,来自聚集索引的键值由所有非聚集索引作为查找键使用,因此存储在每个非聚集索引的叶条目内。

SQL Server提供的3种恢复模型都是什么? 有什么区别?

SQL Server提供了3种恢复模型,分别是:

l         简单恢复 ,允许将数据库恢复到最新的备份。

l         完全恢复,允许将数据库恢复到故障点状态。

l         大容量日志记录恢复,允许大容量日志记录操作。

这些模型中的每个都是针对不同的性能、磁盘和磁带空间以及保护数据丢失的需要。例如,当选择恢复模型时,必须考虑下列业务要求之间的权衡:

l         大规模操作的性能(如创建索引或大容量装载)。

l         数据丢失表现(如已提交的事务丢失)。

l         事务日志空间损耗

l         备份和恢复过程的简化。

根据正在执行的操作,可以有多个适合的模型。选择了恢复模型后,设计所需的备份和恢复过程。表6提供了三种恢复模型的优点和含义的概述。

6备份模型之间的比较

恢复模型

优点

工作损失表现

能否恢复到即时点?

简单

允许高性能大容量复制操作。

收回日志空间以使空间要求最小。

必须重做自最新的数据库或差异备份后所发生的更改。

可以恢复到任何备份的结尾处。随后必须重做更改。

完全

数据文件丢失或损坏不会导致工作损失。

可以恢复到任意即时点(例如,应用程序或用户错误之前)。

正常情况下没有。

如果日志损坏,则必须重做自最新的日志备份后所发生的更改。

可以恢复到任何即时点。

大容量日志记录的

允许高性能大容量复制操作。大容量操作使用最少的日志空间。

如果日志损坏,或者自最新的日志备份后发生了大容量操作,则必须重做自上次备份后所做的更改。否则不丢失任何工作。

可以恢复到任何备份的结尾处。随后必须重做更改。

简单恢复所需的管理最少。在简单恢复模型中,数据只能恢复到最新的完整数据库备份或差异备份的状态。不使用事务日志备份,而使用最小事务日志空间。一旦不再需要日志空间从服务器故障中恢复,日志空间便可重新使用。与完整模型或大容量日志记录模型相比,简单恢复模型更容易管理,但如果数据文件损坏,则数据损失表现会更高。

完全恢复和大容量日志记录恢复模型为数据提供了最大的保护性。这些模型依靠事务日志提供完全的可恢复性,并防止最大范围的故障情形所造成的工作损失。完全恢复模型提供最大的灵活性,可将数据库恢复到更早的即时点。

大容量日志记录模型为某些大规模操作(如创建索引或大容量复制)提供了更高的性能和更低的日志空间损耗。不过这将牺牲时点恢复的某些灵活性。很多数据库都要经历大容量装载或索引创建的阶段,因此可能希望在大容量日志记录模型和完全恢复模型之间进行切换。

SQL Server的固定数据库角色都有哪些?对应的服务器权限有哪些?

固定服务器角色

对应的服务器级权限

bulkadmin

授予的权限: ADMINISTER BULK OPERATIONS

dbcreator

授予的权限: CREATE DATABASE

diskadmin

授予的权限: ALTER RESOURCES

processadmin

授予的权限: ALTER SERVER STATE

processadmin

授予的权限: ALTER ANY CONNECTION

securityadmin

授予的权限: ALTER ANY LOGIN

serveradmin

授予的权限: ALTER SETTINGS

serveradmin

授予的权限: SHUTDOWN

serveradmin

授予的权限: CREATE ENDPOINT

serveradmin

授予的权限: ALTER SERVER STATE

serveradmin

授予的权限: ALTER ANY ENDPOINT

serveradmin

授予的权限: ALTER RESOURCES

setupadmin

授予的权限: ALTER ANY LINKED SERVER

sysadmin

带GRANT 选项授予的权限:CONTROL SERVER

 

 

SQL Server中创建数据库主要有那种方式?

SQL Server中创建数据库主要有两种方法,第一种是在SQL Server Management Studio中使用向导创建数据库;第二种是执行Transact-SQL语句创建数据库。下面我们分别进行介绍。

1)使用SQL Server Management Studio创建数据库

SQL Server Management Studio中,可以使用向导创建数据库,步骤如下:

1.  打开SQL Server Management Studio。

2.     右击“数据库”对象,在弹出式菜单中选择“新建数据库”菜单项,打开“新建数据库”对话框

3.  在“常规”页,可以定义数据库的名称为EAMS、数据库文件、数据库的所有者、排序规则、恢复模型,以及是否使用全文索引。

4.    在“选项”页,可以定义数据库的一些选项,包括自动选项、游标选项、混杂选项、恢复选项、行级版本选项和状态选项

5.    在“文件组”页,显示文件组和文件的统计信息,同时还可以设置是否采用默认值

6.  在“扩展属性”页,可以定义数据库的一些扩展属性,如图5所示。

7.  当完成各个选项的定义之后,单击【OK】按钮,SQL Server数据库引擎会创建所定义的数据库。

2)使用Transact-SQL创建数据库

Transact-SQL提供了创建数据库的语句:CREATE DATABASE,其语法格式如下:

CREATE DATABASE database_name

[ ON

[ [ ,...n ] ]

[ , [ ,...n ] ]

]

[

[ LOG ON { [ ,...n ] } ]

[ COLLATE collation_name ]

[ FOR { ATTACH [ WITH ]

| ATTACH_REBUILD_LOG } ]

[ WITH ]

]

[;]

::=

[ PRIMARY ]

(

[ NAME = logical_file_name , ]

FILENAME = ‘os_file_name’

[ , SIZE = size [ KB | MB | GB | TB ] ]

[ , MAXSIZE = { max_size [ KB | MB | GB | TB ] | UNLIMITED } ]

[ , FILEGROWTH = growth_increment [ KB | MB | % ] ]

) [ ,...n ]

::=

FILEGROUP filegroup_name

[ ,...n ]

::=

DB_CHAINING { ON | OFF }

| TRUSTWORTHY { ON | OFF }

::=

ENABLE_BROKER

| NEW_BROKER

| ERROR_BROKER_CONVERSATIONS

Create a Database Snapshot

CREATE DATABASE database_snapshot_name

ON

(

NAME = logical_file_name,

FILENAME = ‘os_file_name’

) [ ,...n ]

AS SNAPSHOT OF source_database_name

[;]

参数说明如下:

l         database_name,新数据库的名称。数据库名称在服务器中必须唯一,并且符合标识符的规则。database_name 最多可以包含 128 个字符,除非没有为日志指定逻辑名。如果没有指定日志文件的逻辑名,则SQL Server会通过向 database_name 追加后缀来生成逻辑名。该操作要求 database_name 在 123 个字符之内,以便生成的日志文件逻辑名少于 128 个字符。

l         ON,指定显式定义用来存储数据库数据部分的磁盘文件(数据文件)。该关键字后跟以逗号分隔的 项列表, 项用以定义主文件组的数据文件。主文件组的文件列表后可跟以逗号分隔的 项列表(可选), 项用以定义用户文件组及其文件。

l         N,占位符,表示可以为新数据库指定多个文件。

l         LOG ON,指定显式定义用来存储数据库日志的磁盘文件(日志文件)。该关键字后跟以逗号分隔的 项列表, 项用以定义日志文件。如果没有指定 LOG ON,将自动创建一个日志文件,该文件使用系统生成的名称,大小为数据库中所有数据文件总大小的 25%。

l         FOR LOAD,支持该子句是为了与早期版本的 SQL Server 兼容。数据库在打开 dbo use only 数据库选项的情况下创建,并且将其状态设置为正在装载。

l         FOR ATTACH,指定从现有的一组操作系统文件中附加数据库。必须有指定第一个主文件的 条目。至于其它 条目,只需要与第一次创建数据库或上一次附加数据库时路径不同的文件的那些条目。必须为这些文件指定 条目。附加的数据库必须使用与 SQL Server 相同的代码页和排序次序创建。应使用 sp_attach_db 系统存储过程,而不要直接使用 CREATE DATABASE FOR ATTACH。只有必须指定 16 个以上的 项目时,才需要使用 CREATE DATABASE FOR ATTACH。 如果将数据库附加到的服务器不是该数据库从中分离的服务器,并且启用了分离的数据库以进行复制,则应该运行 sp_removedbreplication 从数据库删除复制。

l         collation_name,指定数据库的默认排序规则。排序规则名称既可以是 Windows 排序规则名称,也可以是 SQL 排序规则名称。如果没有指定排序规则,则将 SQL Server 实例的默认排序规则指派为数据库的排序规则。

l         PRIMARY,指定关联的 列表定义主文件。主文件组包含所有数据库系统表。还包含所有未指派给用户文件组的对象。主文件组的第一个 条目成为主文件,该文件包含数据库的逻辑起点及其系统表。一个数据库只能有一个主文件。如果没有指定 PRIMARY,那么 CREATE DATABASE 语句中列出的第一个文件将成为主文件。

l         NAME,为由 定义的文件指定逻辑名称。如果指定了 FOR ATTACH,则不需要指定 NAME 参数。

l         logical_file_name,用来在创建数据库后执行的 Transact-SQL 语句中引用文件的名称。logical_file_name 在数据库中必须唯一,并且符合标识符的规则。该名称可以是字符或 Unicode 常量,也可以是常规标识符或定界标识符。

l         FILENAME,为 定义的文件指定操作系统文件名。

l         os_file_name,操作系统创建 定义的物理文件时使用的路径名和文件名。os_file_name 中的路径必须指定 SQL Server 实例上的目录。os_file_name 不能指定压缩文件系统中的目录。如果文件在原始分区上创建,则 os_file_name 必须只指定现有原始分区的驱动器字母。每个原始分区上只能创建一个文件。原始分区上的文件不会自动增长;因此,os_file_name 指定原始分区时,不需要指定 MAXSIZE 和 FILEGROWTH 参数。

l         SIZE,指定 中定义的文件的大小。如果主文件的 中没有提供 SIZE 参数,那么 SQL Server 将使用 model 数据库中的主文件大小。如果次要文件或日志文件的 中没有指定 SIZE 参数,则 SQL Server 将使文件大小为 1 MB。

l         Size, 中定义的文件的初始大小。可以使用千字节 (KB)、兆字节 (MB)、千兆字节 (GB) 或兆兆字节 (TB) 后缀。默认值为 MB。指定一个整数,不要包含小数位。size 的最小值为 512 KB。如果没有指定 size,则默认值为 1 MB。为主文件指定的大小至少应与 model 数据库的主文件大小相同。

l         MAXSIZE,指定 中定义的文件可以增长到的最大大小。

l         max_size, 中定义的文件可以增长到的最大大小。可以使用千字节 (KB)、兆字节 (MB)、千兆字节 (GB) 或兆兆字节 (TB) 后缀。默认值为 MB。指定一个整数,不要包含小数位。如果没有指定 max_size,那么文件将增长到磁盘变满为止。

l         UNLIMITED,指定 中定义的文件将增长到磁盘变满为止。

l         FILEGROWTH,指定 中定义的文件的增长增量。文件的 FILEGROWTH 设置不能超过 MAXSIZE 设置。

l         growth_increment,每次需要新的空间时为文件添加的空间大小。指定一个整数,不要包含小数位。0 值表示不增长。该值可以 MB、KB、GB、TB 或百分比 (%) 为单位指定。如果未在数量后面指定 MB、KB 或 %,则默认值为 MB。如果指定 %,则增量大小为发生增长时文件大小的指定百分比。如果没有指定 FILEGROWTH,则默认值为 10%,最小值为 64 KB。指定的大小舍入为最接近的 64 KB 的倍数。

l         ,控制文件组的属性。文件组不能在数据库快照上定义。

l         FILEGROUP,定义文件组的逻辑名。

l         filegroup_name,表示在创建数据库之后,在Transact-SQL语句中引用文件组的名称。filegroup_name在数据库中必须唯一,不能是系统提供的名称,如PRIMARY和PRIMARY_LOG。名称必须同标识符的规则保持一致。

l         default,定义文件组为特定文件组类型的默认数据库文件组。

l         DB_CHAINING { ON | OFF },当设置为ON的时候,数据库可以为交叉数据库所有者关系链中的源或者目标。当设置为OFF的时候,数据库不能参与交叉数据库所有者关系链,对于用户数据库,可以修改这个选项,但是不能修改系统数据库的该选项。默认值为OFF。

l         TRUSTWORTHY { ON | OFF },当设置为ON的时候,数据库模块(如视图、用户自定义函数或者存储过程)允许访问数据库外的资源。当设置为OFF的时候,数据库模块不能访问数据库之外的资源。默认值为OFF。

l         ,当授予FOR ATTACH子句的时候,才能设置Service Broker选项。

l         ENABLE_BROKER,定义数据库是否启用Service Broker。

l         NEW_BROKER,在sys数据库中和恢复数据库中创建新的service_broker_guid。

l         ERROR_BROKER_CONVERSATIONS,终止所有发生错误的会话。

l         database_snapshot_name,定义新数据库的快照名。

l         ON (NAME =logical_file_name, FILENAME =’os_file_name’) [ ,... n ] ,对于创建一个数据库快照,在源数据库中定义文件列表。

l         AS SNAPSHOT OF source_database_name,定义创建的数据库为一个源数据库的数据库快照。

几道数据库的面试题或笔试题难度适中

1.张表,学生表S,课程C,学生课程表SC,学生可以选修多门课程,一门课程可以被多个学生选修,通过SC表关联;(SQL)
1)写出建表语句;
答:建表语句如下(mysql数据库):
create table s(id integer primary key, name varchar(20));
create table c(id integer primary key, name varchar(20));
create table sc(
sid integer references s(id),
cid integer references c(id),
primary key(sid,cid)
);
2)写出SQL语句,查询选修了所有选修课程的学生;
答:SQL语句如下:
select stu.id, stu.name from s stu
where (select count(*) from sc where sid=stu.id) =
(select count(*) from c);
3)写出SQL语句,查询选修了至少5门以上的课程的学生。
答:SQL语句如下:
select stu.id, stu.name from s stu
where (select count(*) from sc where sid=stu.id)>=5;

2.数据库表(Test)结构如下:(SQL)
IDNAMEAGEMANAGER(所属主管人ID)
106A30104
109B19104
104C20111
107D35109
112E25120
119F45NULL
要求:列出所有年龄比所属主管年龄大的人的ID和名字?
答:SQL语句如下:
select employee.name from test employee where employee.age>
(select manager.age from test manager where manager.id=employee.manager);

3.有3个表(15分钟):(SQL)
Student 学生表 (学号,姓名,性别,年龄,组织部门)
Course 课程表 (编号,课程名称)
Sc 选课表 (学号,课程编号,成绩)
表结构如下:

1)写一个SQL语句,查询选修了’计算机原理’的学生学号和姓名(3分钟)
答:SQL语句如下:
select stu.sno, stu.sname from Student stu
where (select count(*) from sc where sno=stu.sno and cno =
(select cno from Course where cname=’计算机原理’)) != 0;
2)写一个SQL语句,查询’周星驰’同学选修了的课程名字(3分钟)
答:SQL语句如下:
select cname from Course where cno in (select cno from sc where sno=(select sno from Student where sname=’周星驰’));
3)写一个SQL语句,查询选修了5门课程的学生学号和姓名(9分钟)
答:SQL语句如下:
select stu.sno, stu.sname from student stu
where (select count(*) from sc where sno=stu.sno) = 5;

ORACLE面试测试题目

1.    解释FUNCTION,PROCEDURE和PACKAGE区别
答:function 和procedure是PL/SQL代码的集合,通常为了完成一个任务。procedure 不需要返回任何值而function将返回一个值在另一方面,Package是为了完成一个商业功能的一组function和procedure的集合。

2.    取某个序列的当前值的PL/SQL语句怎么写?
答:SELECT 序列名.CURRVAL  FROM  DUAL;

3.    说明ORACLE数据库实例与ORACLE用户的关系?
答:实例可以包含多个用户,一个用户只能在一个实例下

4.    创建数据库时,自动建立的tablespace名称?
答:SYSTEM tablespace

5.    创建用户时,需要赋予新用户什么权限才能使它连上数据库?
答:CONNECT

6.    IMPORT和SQL*LOADER这2个工具的不同点?
答:这两个ORACLE工具都是用来将数据导入数据库的。
区别是:IMPORT工具只能处理由另一个ORACLE工具EXPORT生成的数据。而SQL*LOADER可以导入不同的ASCII格式的数据源。

7.解释冷备份和热备份的不同点以及各自的优点?
答:热备份针对归档模式的数据库,在数据库仍旧处于工作状态时进行备份。而冷备份指在数据库关闭后,进行备份,适用于所有模式的数据库。热备份的优点在于当备份时,数据库仍旧可以被使用并且可以将数据库恢复到任意一个时间点。冷备份的优点在于它的备份和恢复操作相当简单,并且由于冷备份的数据库可以工作在非归档模式下,数据库性能会比归档模式稍好。(因为不必将archive log写入硬盘)

8.比较truncate和delete命令?
答:两者都可以用来删除表中所有的记录。区别在于:truncate是DDL(data defining language数据定义语言),它移动HWK,不需要rollback segment(处理事务回滚操作)而Delete是DML(data manufacturing language数据操作语言)操作,需要rollback segment(处理事务回滚操作)且花费较长时间。

9.给出数据的相关约束类型?
答:主键约束,外键约束,非空约束,唯一约束,检查约束。

10.说明索引的类型与作用?
答:索引类型上分为聚集索引,非聚集索引其作用是加快查询速度。

11.解释归档和非归档模式之间的不同和它们各自的优缺点
答:归档模式是指你可以备份所有的数据库 transactions并恢复到任意一个时间点。非归档模式则相反,不能恢复到任意一个时间点。但是非归档模式可以带来数据库性能上的少许提高。

12.解释$ORACLE_HOME和$ORACLE_BASE的区别?
答:ORACLE_BASE是oracle的根目录,ORACLE_HOME是oracle产品的目录。

13.获取某个字符字段的最后3个字符的函数是什么?
答:select substr (字段,(length(字段)-3)) from 表

14.取当前系统时间点日期(不包括年月)的SQL写法是怎样的?
答:Select substr (to_char(sysdate,’YYYYMMDDh24hh:MM:SS’),5) from dual;

15.返回大于等于N的最小整数值?
答:select ceil(N) from dual;

16.将根据字符查询转换后结果,规则为:’A’转换为’男’,’B’转换为’女’,其他字符转换为’未知’,请用一个SQL语句写出。
答:select decode(字符,’A’,’男’,’B’,’女’,’未知’) from dual;

17.如何搜索出前N条记录?
答:select * from 表 where  Rownum <= N;

18.如何搜索出第N~M条记录?
答:select * from 表 where Rownum <= M
Minus
select * from 表 where Rownum <= N;

19.有一个数据表(TEST),字段如下:
ID      number
PARENT_ID      number
NAME      Varchar(20)
请使用PL/SQL来按父子层次关系查询出该表的所有数据
答:Select * from test a, test b Where a.parent_id = b.id;

20.怎样用SQL语句实现查找一列中的第N大值?
答:select * from (select * from 表 order by 列名 Desc) where Rownum <= N
Minus
select * from (select * from 表 order by 列名 Desc) where Rownum <= N-1;

腾讯公司的一个sql题

小小+霸霸+王王=小霸王
=?,霸=?,王=?
sql求证

参考答案:

declare @data int,@i int,@j int,@l int
set @data=100
while (@data<=999)
begin
   set @i=@data/100
   set @j=@data/10 % 10
   set @l=@data % 10
   if((@i+@j+@l)*11=@data)
   begin
      Select @data data,@i i,@j j,@l l
      break
   end
   set @data=@data+1
end;
分析:
II+JJ+LL=IJL
I*10+I +J*10+J+L*10+L   =   I*100+J*10+L
(I+J+L)*11

1、 一套Oracle面试题笔试题

完成下列操作,写出相应的SQL语句

1. 创建表空间neuspace,数据文件命名为neudata.dbf,存放在d:\data目录下,文件大小为200MB,设为自动增长,增量5MB,文件最大为500MB。(8分)

答:create tablespace neuspace datafile ‘d:\data\neudata.dbf’ size 200m auto extend on next 5m maxsize 500m;

2. 假设表空间neuspace已用尽500MB空间,现要求增加一个数据文件,存放在e:\appdata目录下,文件名为appneudata,大小为500MB,不自动增长。(5分)

答:alter tablespace neuspace add datafile ‘e:\appdata\appneudata.dbf’ size 500m;

3. 以系统管理员身份登录,创建账号tom,设置tom的默认表空间为neuspace。为tom分配connect和resource系统角色,获取基本的系统权限。然后为tom分配对用户scott的表emp的select权限和对SALARY, MGR属性的update权限。(8分)

答:create user tom identified by jack default tablespace neuspace;

Grant connect, resource to tom;

Grant select, update(salary, mgr) on scott.emp to tom;

4. 按如下要求创建表class和student。(15分)

属性

类型(长度)

默认值

约束

含义

CLASSNO

数值 (2)

主键

班级编号

CNAME

变长字符 (10)

非空

班级名称

 

属性

类型(长度)

默认值

约束

含义

STUNO

数值 (8)

主键

学号

SNAME

变长字符 (12)

非空

姓名

SEX

字符 (2)

性别

BIRTHDAY

日期

生日

EMAIL

变长字符 (20)

唯一

电子邮件

SCORE

数值 (5, 2)

检查

成绩

CLASSNO

数值 (2)

外键,关联到表CLASS的CLASSNO主键

班级编号

答:create table class

(classno number(2) constraint class_classno_pk primary key,

cname varchar2(10) not null);

create table student

(stuno number(8) constraint student_stuno_pk primary key,

sname varchar2(12) not null,

sex char(2) default ‘男’,

birthday date,

email varchar2(20) constraint student_email_uk unique,

score number(5,2) constraint student_score_ck check(score>=0 and score<=100),

classno number(2) constraint student_classno_fk references class(classno)

);

5. 在表student的SNAME属性上创建索引student_sname_idx(5分)

答:create index student_sname_idx on student(sname);

6. 创建序列stuseq,要求初值为20050001,增量为1,最大值为20059999。(6分)

答:create sequence stuseq increment by 1 start with 20050001 maxvalue 20059999 nocache nocycle;

7. 向表student中插入如下2行。(5分)

STUNO

SNAME

SEX

BIRTHDAY

EMAIL

SCORE

CLASSNO

从stuseq取值

tom

1979-2-3 14:30:25

[email protected]

89.50

1

从stuseq取值

jerry

默认值

2

答:insert into student values(stuseq.nextval, ’tom’, ’男’, to_date(‘1979-2-3

14:30:25’, ’yyyy-mm-dd fmhh24:mi:ss’), ’[email protected]’, 89.50, 1);

insert into student (stuno, sname, classno) values(stuseq.nextval, ’jerry’, 2);

8. 修改表student的数据,将所有一班的学生成绩加10分。(4分)

答:update student set score=score+10 where classno=1;

9. 删除表student的数据,将所有3班出生日期小于1981年5月12日的记录删除。(4分)

答:delete from student where classno=3 and birthday > ’12-5月-81’;

10. 完成以下SQL语句。(40分)

(1) 按班级升序排序,成绩降序排序,查询student表的所有记录。

答:select * from student order by classno, score desc;

(2) 查询student表中所有二班的成绩大于85.50分且出生日期大于1982-10-31日的男生的记录。

答:select * from student where classno=2 and score>85.50 and birthday < ’31-10月-82’ and sex=’男’;

(3) 查询student表中所有三班成绩为空的学生记录。

答:select * from student where classno=3 and score is null;

(4) 表student与class联合查询,要求查询所有学生的学号,姓名,成绩,班级名称。(使用oracle与SQL 99两种格式)

答:select s.stuno, s.sname, s.score, c.cname from student s, class c where s.classno=c.classno;

(5) 按班级编号分组统计每个班的人数,最高分,最低分,平均分,并按平均分降序排序。

答:select classno, count(*), max(score), min(score), avg(score) from student group by classno order by avg(score) desc;

(6) 查询一班学生记录中所有成绩高于本班学生平均分的记录。

答:select * from student where classno=1 and score > (select avg(score) from student where classno=1);

(7) 统计二班学生中所有成绩大于所有班级平均分的人数。

答:select count(*) from student where classno=2 and score > all (select avg(socre) from student group by classno);

(8) 查询平均分最高的班级编号与分数。

答:select classno, avg(score) from student group by classno having avg(score) = (select max(avg(score)) from student group by classno);

(9) 查询所有学生记录中成绩前十名的学生的学号、姓名、成绩、班级编号。

答:select stuno, sname, score, classno from (select * from student order by score desc) where rownum<=10;

(10) 创建视图stuvu,要求视图中包含student表中所有一班学生的stuno, sname, score, classno四个属性,并具有with check option限制。

答:create view stuvu

as

select stuno, sname,score,classno from student where classno=1 with check option;

2、 一道Oracle笔试题

表结构说明:
create table employee(
id number(10) not null, — 员工工号
salary number(10,2) default 0 not null, — 薪水
name varchar2(24) not null — 姓名
);
1.创建序列seq_employee,该序列每次取的时候它会自动增加,从1开始计数,不设最大值,并且一直累加,不循环。(10分)
2.写一个PL/SQL块,插入表user.employee中100条数据。插入该表中字段id用序列seq_employee实现,薪水和姓名字段可以任意填写。(15分)

 

6.写一个匿名语句块,用于执行函数f_employee,并打印执行该函数的结果。(8分)
7.创建存储过程p_create_emp,用于判断表employee是否存在,如果存在则删除该表。(15分)
8.写一个匿名语句块,用于执行存储过程p_create_emp。(7分)
答案如下:
SQL> create table employee(
2 id number(10) not null, — 员工工号
3 salary number(10,2) default 0 not null, — 薪水
4 name varchar2(24) not null — 姓名
5 );
表已创建。
—第一题答案:
SQL> Create sequence seq_employee increment by 1 start with 1 nomaxvalue nocycle;
序列已创建。
—第二题答案:
SQL> declare i number;
2 begin
3 for i in 1 .. 100
4 loop
5 insert into employee
6 values(seq_employee.nextval,1950+i,’王明’||to_char(i));
7 commit;
8 end loop;
9 end;
10 /
PL/SQL 过程已成功完成。
SQL> select * from employee where rownum<11;
ID SALARY NAME
———- ———- ————————
1 1951 王明1
2 1952 王明2
3 1953 王明3
4 1954 王明4
5 1955 王明5
6 1956 王明6
7 1957 王明7
8 1958 王明8
9 1959 王明9
10 1960 王明10
已选择10行。
3.写一个语句块,在语句块中定义一个显式游标,按id升序排列,打印表employee中前十条数据。(15分)
——-第三题答案:
SQL> declare
2 cursor c is select id,salary,name from(select * from employee order by id) where rownum<11;
3 v_record c%rowtype;
4 begin
5 open c;
6 loop
7 fetch c into v_record;
8 exit when c%notfound;
9 dbms_output.put_line(to_char(v_record.id)||’,'||to_char(v_record.salary)||’,'||v_record.name);
10 end loop;
11 close c;
12 end;
13 /
1,1951,王明1
2,1952,王明2
3,1953,王明3
4,1954,王明4
5,1955,王明5
6,1956,王明6
7,1957,王明7
8,1958,王明8
9,1959,王明9
10,1960,王明10
PL/SQL 过程已成功完成。
4.创建存储过程p_employee,输入员工薪水范围,返回员工工号、姓名、薪水结果集,结果集按员工薪水升序排列。(15分)
——-第四题答案
SQL> create or replace procedure p_employee
2 (iminsalary in number,
3 imaxsalary in number)
4 is
5 begin
6 for x in(select id,salary,name from(select * from employee where salary between iminsalary and imaxsalary) order by salary)
7 loop
8 dbms_output.put_line(to_char(x.id)||to_char(x.salary)||x.name);
9 end loop;
10 end;
11 /
过程已创建。
SQL> exec p_employee(2000,2007);
502000王明50
512001王明51
522002王明52
532003王明53
542004王明54
552005王明55
562006王明56
572007王明57
PL/SQL 过程已成功完成。
5.创建函数f_employee实现更新员工薪水的功能,将薪水低于2000且姓wang的员工薪水加5%,其他不变,更新成功则返回0,否则返回1。(15分)
———第五题答案
SQL> create or replace function f_employee return number
is
begin
update employee set salary=salary+salary*0.05 where salary<2000 and name like ‘王%’;
commit;
if sql%rowcount=0 then
return 1;
else
return 0;
end if;
end;
/
函数已创建。
—–第六题答案
SQL> declare a number;
2 begin
3 a:=f_employee();
4 dbms_output.put_line(to_char(a));
5 end;
6 /
0
PL/SQL 过程已成功完成。
SQL> select * from employee where salary<2000 and name like ‘王%’;
未选定行
SQL> select * from employee where rownum<50;
ID SALARY NAME
———- ———- ————————
1 2048.55 王明1
2 2049.6 王明2
3 2050.65 王明3
4 2051.7 王明4
5 2052.75 王明5
6 2053.8 王明6
7 2054.85 王明7
8 2055.9 王明8
9 2056.95 王明9
10 2058 王明10
11 2059.05 王明11
ID SALARY NAME
———- ———- ————————
12 2060.1 王明12
13 2061.15 王明13
14 2062.2 王明14
15 2063.25 王明15
16 2064.3 王明16
17 2065.35 王明17
18 2066.4 王明18
19 2067.45 王明19
20 2068.5 王明20
21 2069.55 王明21
22 2070.6 王明22
ID SALARY NAME
———- ———- ————————
23 2071.65 王明23
24 2072.7 王明24
25 2073.75 王明25
26 2074.8 王明26
27 2075.85 王明27
28 2076.9 王明28
29 2077.95 王明29
30 2079 王明30
31 2080.05 王明31
32 2081.1 王明32
33 2082.15 王明33
ID SALARY NAME
———- ———- ————————
34 2083.2 王明34
35 2084.25 王明35
36 2085.3 王明36
37 2086.35 王明37
38 2087.4 王明38
39 2088.45 王明39
40 2089.5 王明40
41 2090.55 王明41
42 2091.6 王明42
43 2092.65 王明43
44 2093.7 王明44
ID SALARY NAME
———- ———- ————————
45 2094.75 王明45
46 2095.8 王明46
47 2096.85 王明47
48 2097.9 王明48
49 2098.95 王明49
已选择49行。
—–第七题答案
SQL> create or replace procedure p_create_emp
2 is
3 v_count number;
4 begin
5 select count(*) into v_count from user_tables where table_name=’EMPLOYEE’;
6 if v_count=0 then
7 return;
8 else
9 execute immediate ‘drop table employee’;
10 end if;
11 end;
12 /
过程已创建。

———第八题答案
SQL> exec p_create_emp;
PL/SQL 过程已成功完成。
SQL> select * from employee;
select * from employee
*
ERROR 位于第 1 行:
ORA-00942: 表或视图不存在

如何查询Oracle数据库中已经创建的索引?

查询数据字典user_indexes和user_ind_columns

例子:

SQL> SELECT ic.index_name, ic.column_name,

2         ic.column_position col_pos,ix.uniqueness

3  FROM    user_indexes ix, user_ind_columns ic

4  WHERE   ic.index_name = ix.index_name

5  AND ic.table_name = ‘S_EMP’;

注意: 数据字典里存放的字符都是大写的.

哪些情况下不应该使用索引?

1. 表很小的情况下,没有必要使用索引

2. 不经常在Where后使用的比较字段

3. 如果表数据需要频繁修改,不建议使用索引

4. 如果查询返回记录很多,不建议使用索引

5. 如果where后含IS NULL /IS NOT NULL/ like ‘%输入符%’等条件,不建议使用索引。

SQL里面如何插入自动增长序列号字段?

INSERT时如果要用到从1开始自动增长的数字做唯一关键字, 应该先建立一个序列号.

CREATE SEQUENCE 序列号的名称 (最好是表名+序列号标记) INCREMENT BY 1 START WITH 1 MAXVALUE 99999 NOCYCLE NOCACHE;

其中最大的值按字段的长度来定,比如定义的自动增长的序列NUMBER(6) , 最大值为999999

INSERT 语句插入这个字段值为: 序列号的名称.NEXTVAL

例子: SQL> insert into s_dept(id, name, region_id) values (s_dept_id.nextval, ‘finance’, 2);

1 row created.

只有运行了序列号的名称. nextval后序列号的名称. currval 才有效才有值.

不用游标的SQL语句有哪些?

1. 说明性语句
2. 数据定义语句
3. 数据控制语句
4. 查询结果为单记录的SELECT语句
5. 非CURRENT形式的UPDATE语句
6. 非CURRENT形式的DELETE语句
7. INSERT语句
所有的说明性语句及数据定义与控制语句都不需要使用游标,他们是嵌入式SQL中最简单的一类语句,不需要返回结果数据,也不需要使用主变量。 在主语言中嵌入说明性语句及数据定义与控制语句,只要给语句加上前缀EXEC SQL 和预计结束符即可。
INSERT语句也不需要使用游标,但通常需要使用主变量
SELECT语句,UPDATE语句,DELETE语句则要复杂些。

必须要使用游标的SQL语句有那些?

必须要使用游标的SQL语句有:
1. 查询结果为多结果的SELECT语句
2. CURRENT形式的UPDATE语句
3. CURRENT形式的DELETE语句

查询优化的一般准则有哪些?

1. 选择运算应尽可能先做。这是优化策略中最重要最基本的一条
2. 在执行连接前对关系适当的预处理,方法有两种:在连接属性上建立索引和对关系排序,然后执行连接,第一种称为索引连接方法,第二种称为排序合并连接方法
3. 把投影运算和选择运算同时进行。
4. 把投影同其前或者其后的双目运算结合起来,没有必要为了去掉某些字段而扫描一下关系
5. 把某些选择同它前面要执行的笛卡尔积结合起来成为一个连接运算,连接特别是等值连接运算要比同样关系上的笛卡尔积节省很多时间
6. 找出公共子表达式,先计算出公共子表达式的值才参与运算。

ORACLE二十问

1. Oracle安裝完成后的初始口令? 

internal/oracle
sys/change_on_install
system/manager
scott/tiger
sysman/oem_temp  

2. ORACLE9IAS WEB CACHE的初始默认用户和密码?  

administrator/administrator 

3. oracle 8.0.5怎么创建数据库?  

orainst。如果有motif界面,可以用orainst /m 

4. oracle 8.1.7怎么创建数据库?

dbassist 

5. oracle 9i 怎么创建数据库? 

dbca  

6. oracle中的裸设备指的是什么?  

裸设备就是绕过文件系统直接访问的储存空间 

7. oracle如何区分 64-bit/32bit 版本??? 

$ sqlplus ‘/ AS SYSDBA’
SQL*Plus: Release 9.0.1.0.0 – Production on Mon Jul 14 17:01:09 2003
(c) Copyright 2001 Oracle Corporation. All rights reserved.
Connected to:
Oracle9i Enterprise Edition Release 9.0.1.0.0 – Production
With the Partitioning option
JServer Release 9.0.1.0.0 – Production
SQL> select * from v$version;
BANNER
Oracle9i Enterprise Edition Release 9.0.1.0.0 – Production
PL/SQL Release 9.0.1.0.0 – Production
CORE 9.0.1.0.0 Production
TNS for Solaris: Version 9.0.1.0.0 – Production
NLSRTL Version 9.0.1.0.0 – Production
SQL>  

8. SVRMGR什么意思? 

svrmgrl,Server Manager.

9i下没有,已经改为用SQLPLUS了

sqlplus /nolog
  变为归档日志型的 

9. 请问如何分辨某个用户是从哪台机器登陆ORACLE的?

SELECT machine , terminal FROM V$SESSION;  

10. 用什么语句查询字段呢? 

desc table_name 可以查询表的结构
select field_name,… from … 可以查询字段的值
select * from all_tables where table_name like ‘%’
select * from all_tab_columns where table_name=’??’  

11. 怎样得到触发器、过程、函数的创建脚本? 

desc user_source
user_triggers   

12. 怎样计算一个表占用的空间的大小? 

select owner,table_name,
NUM_ROWS,
BLOCKS*AAA/1024/1024 “Size M”,
EMPTY_BLOCKS,
LAST_ANALYZED
from dba_tables
where table_name=’XXX’;
Here: AAA is the value of db_block_size ;
XXX is the table name you want to check 

14. 如何查看系统被锁的事务时间?
select * from v$locked_object ;

15. 如何以archivelog的方式运行oracle。
init.ora
log_archive_start = true
RESTART DATABASE
16. 怎么获取有哪些用户在使用数据库
select username from v$session;

17. 数据表中的字段最大数是多少?

  表或视图中的最大列数为 1000  

18. 怎样查得数据库的SID ?

select name from v$database;

  也可以直接查看 init.ora文件

19. 如何在Oracle服务器上通过SQLPLUS查看本机IP地址 ?

select sys_context(’userenv’,'ip_address’) from dual;

  如果是登陆本机数据库,只能返回127.0.0.1,呵呵  

20. unix 下怎么调整数据库的时间?

su -root

date -u 08010000

 

如何高效率的查找一个月以内的数据?

进行时间比较要尽量避免用sysdate. 比如:如果使用select * from eventtable where eventdate>sysdate-30进行查找,当数据量小的时候看不出来,数据量大一些就会发现执行很慢,但日期型字 段上也是有索引的,为什么会慢呢? 原来是Oracle在进行查找的时候不断地去取sysdate这个不断变化的值,而不是我们想象中的一次产生一个条件语句然后进行查找。为了加快速度,我 们可以先把当天的日期取出来,然后转成字符串后再用如下语句查,select * from eventtable where eventdate > to_date(’2001-12-1′,’yyyy-mm-dd’)。速度相差几十倍。

Oracle怎样计算一个表占用的空间的大小?

可以使用一下语句来进行计算:

select owner ,
table_name,
NUM_ROWS,
BLOCKS*AAA/1024/1024 “Size M”,
EMPTY_BLOCKS,
LAST_ANALYZED
from dba_tables
where table_name= XXX ;
AAA 是指 db_block_size的值 ;
XXX 是你要查询的表名

如何在Oracle中查看各个表、表空间占用空间的大小?

使用以下语句查看当前用户每个表占用空间的大小:
Select Segment_Name,Sum(bytes)/1024/1024 From User_Extents Group By Segment_Name

使用一下语句查看每个表空间占用空间的大小:
Select Tablespace_Name,Sum(bytes)/1024/1024 From Dba_Segments Group By Tablespace_Name

介绍一下Oracle的操作符优化?

IN :

IN写出来的SQL比较容易写及清晰易懂但是性能总是比较低的,从ORACLE执行的步骤来分析用IN的SQL与不用IN的SQL有以下区别:

ORACLE 试图将IN转换成多个表的连接,如果转换不成功会先执行IN里面的子查询,再查询外层的表记录,如果转换成功,则直接采用多个表的连接方式查询。所以用 IN的SQL至少多了一个转换的过程。一般的SQL都可以转换成功,但对于含有分组统计等方面的SQL就不能转换了。

推荐方法:在业务密集的SQL当中尽量不要采用IN操作符。

NOT IN:

不推荐使用,因为NOT IN不能应用表的索引。

推荐方案:用NOT EXISTS 或(外连接+判断为空)

<> 操作符(不等于)

不等于操作符不会用到索引的,对它的处理只会产生全表扫描。

推荐方案:用其它相同功能的操作运算代替,如 a<>0 改为 a>0 or a<0  a<>’’ 改为 a>’’

IS NULL 或IS NOT NULL操作(判断字段是否为空)

判断字段是否为空一般不会应用索引,因为B树索引是不索引空值的。

推荐方案:

用其它相同功能的操作运算代替,如 a is not null 改为 a>0 或a>’’等。

不允许字段为空,而用一个缺省值代替空值,如业扩申请中状态字段不允许为空,缺省为申请。

建立位图索引(有分区的表不能建,位图索引比较难控制,如字段值太多索引会使性能下降,多人更新操作会增加数据块锁的现象)。

> 及 < 操作符(大于或小于操作符)

大于或小于操作符一般不用调整,因为它有索引就会采用索引查找,但有的情况下可以对它进行优化,如一个表有100万记录,一个数值型字段A, 30万记录的A=0,30万记录的A=1,39万记录的A=2,1万记录的A=3。那么执行A>2与A>=3的效果就有很大的区别了,因为 A>2时ORACLE会先找出为2的记录索引再进行比较,而A>=3时ORACLE则直接找到=3的记录索引。

LIKE:

LIKE 操作符可以应用通配符查询,里面的通配符组合可能达到几乎是任意的查询,但是如果用得不好则会产生性能上的问题,如LIKE ‘%5400%’ 这种查询不会引用索引,而LIKE ‘X5400%’则会引用范围索引。一个实际例子:用YW_YHJBQK表中营业编号后面的户标识号可来查询营业编号 YY_BH LIKE ‘%5400%’ 这个条件会产生全表扫描,如果改成YY_BH LIKE ’X5400%’ OR YY_BH LIKE ’B5400%’ 则会利用YY_BH的索引进行两个范围的查询,性能肯定大大提高。

Oracle如何查询登陆客户端的机器名?

可以用一下语句查询登陆客户端的机器名:

select machine, terminal from V$SESSION

如何提高MySql的安全性?

1.如果MYSQL客户端和服务器端的连接需要跨越并通过不可信任的网络,那么需要使用ssh隧道来加密该连接的通信。

2.使用set password语句来修改用户的密码,先“mysql -u root”登陆数据库系统,然后“mysql> update mysql.user set password=password(’newpwd’)”,最后执行“flush privileges”就可以了。

3.Mysql需要提防的攻击有,防偷听、篡改、回放、拒绝服务等,不涉及可用性和容错方面。对所有的连接、查询、其他操作使用基于acl即访问控制列表的安全措施来完成。也有一些对ssl连接的支持。

4.设置除了root用户外的其他任何用户不允许访问mysql主数据库中的user表;

加密后存放在user表中的加密后的用户密码一旦泄露,其他人可以随意用该用户名/密码相应的数据库;

5.使用grant和revoke语句来进行用户访问控制的工作;

6.不要使用明文密码,而是使用md5()和sha1()等单向的哈系函数来设置密码;

7.不要选用字典中的字来做密码;

8.采用防火墙可以去掉50%的外部危险,让数据库系统躲在防火墙后面工作,或放置在dmz区域中;

9.从因特网上用nmap来扫描3306端口,也可用telnet server_host 3306的方法测试,不允许从非信任网络中访问数据库服务器的3306号tcp端口,需要在防火墙或路由器上做设定;

10.为了防止被恶意传入非法参数,例如where id=234,别人却输入where id=234 or 1=1导致全部显示,所以在web的表单中使用”或”"来用字符串,在动态url中加入%22代表双引号、%23代表井号、%27代表单引号;传递未检查过的值给mysql数据库是非常危险的;

11.在传递数据给mysql时检查一下大小;

12.应用程序需要连接到数据库应该使用一般的用户帐号,开放少数必要的权限给该用户;

$page_devide$

13.在各编程接口(c c++ php perl java jdbc等)中使用特定‘逃脱字符’函数;

在因特网上使用mysql数据库时一定少用传输明文的数据,而用ssl和ssh的加密方式数据来传输;

14.学会使用tcpdump和strings工具来查看传输数据的安全性,例如tcpdump -l -i eth0 -w -src or dst port 3306 strings。以普通用户来启动mysql数据库服务;

15.不使用到表的联结符号,选用的参数 –skip-symbolic-links;

16.确信在mysql目录中只有启动数据库服务的用户才可以对文件有读和写的权限;

17.不许将process或super权限付给非管理用户,该mysqladmin processlist可以列举出当前执行的查询文本;super权限可用于切断客户端连接、改变服务器运行参数状态、控制拷贝复制数据库的服务器;

18.file权限不付给管理员以外的用户,防止出现load data ‘/etc/passwd’到表中再用select 显示出来的问题;

19.如果不相信dns服务公司的服务,可以在主机名称允许表中只设置ip数字地址;

20.使用max_user_connections变量来使mysqld服务进程,对一个指定帐户限定连接数;

21.grant语句也支持资源控制选项;

22.启动mysqld服务进程的安全选项开关,–local-infile=0或1 若是0则客户端程序就无法使用local load data了,赋权的一个例子grant insert(user) on mysql.user to ‘user_name’@'host_name’;若使用–skip-grant-tables系统将对任何用户的访问不做任何访问控制,但可以用 mysqladmin flush-privileges或mysqladmin reload来开启访问控制;默认情况是show databases语句对所有用户开放,可以用–skip-show-databases来关闭掉。

23.碰到error 1045(28000) access denied for user ‘root’@'localhost’ (using password:no)错误时,你需要重新设置密码,具体方法是:先用–skip-grant-tables参数启动mysqld,然后执行 mysql -u root mysql,mysql>update user set password=password(’newpassword’) where user=’root’;mysql>flush privileges;,最后重新启动mysql就可以了。

什么是ddl dml和dcl?

DDL :数据定义语言,用于定义和管理 SQL 数据库中的所有对象的语言
1.CREATE – to create objects in the database   创建数据库对象
2.ALTER – alters the structure of the database   修改数据库对象
3.DROP – delete objects from the database   删除数据库对象
4.TRUNCATE – remove all records from a table, including all spaces allocated for the records are removed
TRUNCATE TABLE [Table Name]。
下面是对Truncate语句在MSSQLServer2000中用法和原理的说明:
Truncate table 表名 速度快,而且效率高,因为:
TRUNCATE TABLE 在功能上与不带 WHERE 子句的 DELETE 语句相同:二者均删除表中的全部行。但 TRUNCATE TABLE 比 DELETE 速度快,且使用的系统和事务日志资源少。
DELETE 语句每次删除一行,并在事务日志中为所删除的每行记录一项。TRUNCATE TABLE 通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中记录页的释放。
TRUNCATE TABLE 删除表中的所有行,但表结构及其列、约束、索引等保持不变。新行标识所用的计数值重置为该列的种子。如果想保留标识计数值,请改用 DELETE。如果要删除表定义及其数据,请使用 DROP TABLE 语句。
对于由 FOREIGN KEY 约束引用的表,不能使用 TRUNCATE TABLE,而应使用不带 WHERE 子句的 DELETE 语句。由于 TRUNCATE TABLE 不记录在日志中,所以它不能激活触发器。
TRUNCATE TABLE 不能用于参与了索引视图的表。
5.COMMENT – add comments to the data dictionary 注释
6.GRANT – gives user’s access privileges to database 授权
7.REVOKE – withdraw access privileges given with the GRANT command   收回已经授予的权限

DML:数据操作语言,SQL中处理数据等操作统称为数据操纵语言
1.SELECT – retrieve data from the a database           查询数据
2.INSERT – insert data into a table                    添加数据
3.UPDATE – updates existing data within a table    更新数据
4.DELETE – deletes all records from a table, the space for the records remain   删除
5.CALL – call a PL/SQL or Java subprogram
6.EXPLAIN PLAN – explain access path to data
Oracle RDBMS执行每一条SQL语句,都必须经过Oracle优化器的评估。所以,了解优化器是如何选择(搜索)路径以及索引是如何被使用的,对优化SQL语句有很大的帮助。Explain可以用来迅速方便地查出对于给定SQL语句中的查询数据是如何得到的即搜索路径(我们通常称为Access Path)。从而使我们选择最优的查询方式达到最大的优化效果。
7.LOCK TABLE – control concurrency 锁,用于控制并发

DCL:数据控制语言,用来授予或回收访问数据库的某种特权,并控制数据库操纵事务发生的时间及效果,对数据库实行监视等
COMMIT – save work done 提交
SAVEPOINT – identify a point in a transaction to which you can later roll back 保存点
ROLLBACK – restore database to original since the last COMMIT   回滚
SET TRANSACTION – Change transaction options like what rollback segment to use   设置当前事务的特性,它对后面的事务没有影响.

什么是数据库的约束?

数据库约束是防止非法记录的规则, 约束保存在数据字典(data dictionary)中, 约束可以被定义在列级或者表级。

Oracle中包括一下集中约束:

1. Not Null – 明确一列数据不能包含null值

2. Unique – 强制所有数据行不能有重复值

3. Primary Key – 每一行数据的唯一标示

4. Foreign Key – 强制一列数据与引用表的外键约束关系

5. Check – 检查,明确规定一个必须为true的condition

Oracle数据库架构中包括几层?每层都有什么元素?

Oracle数据库包括一个逻辑层和物理层,物理层包括Oracle磁盘上的文件, 逻辑层用来映射数据和物理层的文件。

逻辑层包括一下元素:

一个或者多个表空间。

数据库Schema: 包括表,集群,索引,视图,存储过程,数据库触发器和sequences.

介绍一下SQL中union, intersect 和 minus

Union用来返回多个查询的结果的总和去掉重复的结果

语法:
SELECT column1, column2 FROM tablename1
UNION
SELECT column1, column2 FROM tablename2;

Intersect 用来返回多个查询中共同的结果,intersect会忽略null值

语法:

SELECT column1, column2 FROM tablename1
INTERSECT
SELECT column1, column2 FROM tablename2;

MUNUS返回出现在第一个查询结果中但是不出现在第二个查询结果的结果集。

语法:

SELECT column1, column2 FROM tablename1
MINUS
SELECT column1, column2 FROM tablename2;

主键(Primary Key)约束和唯一性(UNIQUE)约束有什么区别?

一个表只能由一个主键,一个表可以有很多个唯一键(UNIQUE Key)

主键不允许有null值,UNIQUE允许null值

Oracle中delete, truncate 和 drop的区别?

Delete命令用来删除表的全部或者一部分数据行,执行delete之后,用户需要提交(commmit)或者回滚(rollback) transaction 来执行删除或者撤销删除, delete命令会触发这个表上所有的delete触发器。

Truncate删除表中的所有数据, 这个操作不能回滚,也不会触发这个表上的触发器,TRUNCATE比delete更快,占用的空间更小。

Drop命令从数据库中删除表, 所有的数据行,索引和权限也会被删除,所有的DML触发器也不会被触发,这个命令也不能回滚。

rowid和rownum有什么不同?

RowId是一个数据库内部的概念,表示表的一行,用来快速的访问某行数据

Rownum是结果集的一个功能, 例如select * from Student where rownum = 2 就是得到结果集的第二行。

视图的作用是什么?

数据库视图的作用只要有:

1. 数据库视图隐藏了数据的复杂性。

2. 数据库视图有利于控制用户对表中某些列的访问。

3. 数据库视图使用户查询变得简单。

视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。

对其中所引用的基础表来说,视图的作用类似于筛选。定义视图的筛选可以来自当前或其它数据库的一个或多个表,或者其它视图。分布式查询也可用于定义使用多个异类源数据的视图。如果有几台不同的服务器分别存储组织中不同地区的数据,而您需要将这些服务器上相似结构的数据组合起来,这种方式就很有用。

通过视图进行查询没有任何限制,通过它们进行数据修改时的限制也很少。

什么是Oracle的同义词(synonym)? 如何创建synonym?

同义词是相当于别名,是为了简化一些表名或者数据对象。 当我们以一个用户登陆而要去访问另一个用户创建的数据对象时,我们需要使用用户名.对象名的方法来使用,这样造成对象名难记,麻烦,使用同义词可以解决这个问题。

假定我们现在以system的身份的登陆进去,我们需要访问scott用户下面的一个表emp;

常规的写法是:select * from scott.emp;

现在我们可以先建立一个同义词:
create synonym my_syn for scott.emp;

然后我们这样来访问这个表了:
select * from my_syn;

什么是数据库锁?Oracle中都有哪些类型的锁?

锁是用来在多个用户同时访问同一个表的时候保护数据的。 它是Oracle的一种并发控制技术。锁使数据库最大并发的情况下保证数据的完整性。 Oracle会在需要的时候自动的提供锁的功能。

锁的种类:

共享锁: 这个锁是数据在被viewed的时候放置的。

排他锁: 这种锁在Insert, Update, Delete命令执行的时候放置的,每一条记录同一时间只能有一个排他锁。

触发器(trigger)的功能都有哪些?写出一个触发器的例子

触发器是数据库中由一个时间触发的特殊的存储过程,他不是由程序条用也不是手工启动的。触发器的执行可以由对一个表的insert,delete, update等操作来触发,触发器经常用于加强数据的完整性约束和业务规则等等。

触发器的功能主要有一下六种:

1、 允许/限制对表的修改

2、 自动生成派生列,比如自增字段

3、 强制数据一致性

4、 提供审计和日志记录

5、 防止无效的事务处理

6、 启用复杂的业务逻辑

Create table foo(a number);
Create trigger biud_foo
Before insert or update or delete
On foo
Begin
If user not in (‘DONNY’) then
Raise_application_error(-20001, ‘You don’t have access to modify this table.’);
End if;
End;

如何杀掉ORACLE里面长期没有释放的锁?

如果一个数据库insert update delete操作很长时间没有反应,就可能出现了没有正常释放的锁。

可以用以下SQL语句杀掉没有正常释放的锁:

alter system kill session ’sid,serial#’;

如何查看当前ORACLE数据库里面锁的情况?

查看数据库锁的情况必须要有DBA权限,可以使用一下SQL 语句:

select object_id,session_id,locked_mode from v$locked_object;

select t2.username,t2.sid,t2.serial#,t2.logon_time

from v$locked_object t1,v$session t2

where t1.session_id=t2.sid order by t2.logon_time;

长时间出现的锁可能是没有正常释放的锁。

Oracle的锁有几种模式?

Oracle里面的锁共有一下几种模式:

0: none

1:  null 空

2:Row-S 行共享(Row Share RS): 共享表锁

3:Row-X 行专用(RX): 用于行数据的修改

4:Share 共享锁(S): 阻止其他DML操作

5:S/Row-X 共享行专用(SRX): 阻止其他事务操作

6:exclusive 专用(X): 独立访问使用

以上可以看出,数字越大的锁影响的操作越多,锁的级别越高。

一般的查询语句是小于2的锁,如select * from *

select … from … for update 是2的锁,这时候返回集的数据行都将处于行级(Row-X)独占式锁定,其他对象只能对这些数据进行查询,而不能进行更新或者select for update操作。

insert/update/delete是3的锁, 在这些操作没有commit之前插入同样的记录会没有反应,因为3的锁必须要等到前一个3的锁执行释放掉以后才能继续。 创建索引的时候也会产生3,4级别的锁。

locked_mod为2,3,4的锁,不影响DML(insert,delete,update,select)操作,但是DDL(alter,drop)等修改表结构的操作会提示ora-00054错误。

当有主外键约束时执行update/delete操作可能会产生4,5的锁。

DDL语句时是6的锁。


你可能感兴趣的:(Java)