Oracle学习时笔记,一些资料

来源:互联网 发布:微信游戏源码 编辑:程序博客网 时间:2024/06/07 04:43

---------------------------------------------------------------------------
-- 简单查询: 显示所有的列,与指定的列
---------------------------------------------------------------------------

--用到表以及含义
 --s_emp:员工表,存放与员工相关的数据
 --s_dept:部门表,存放与部门相关的数据
 
--查询语句
--选取指定的列
--请查出所有员工,显示ID,first_name,last_name
select
 id, first_name, last_name
from
   s_emp;

--sql语句的要素:
 --keyword
 --sql子句
 --sql语句
 --注意:大小写不敏感,可以换行,关于“;”号,
 --显示的列名大写,对齐方式
 --select :列与列之间用","分割
 --from
 --理解:sql子句执行的顺序
 --练习:选取所有的部门,显示ID,NAME,REGION_ID

--如何知到指定的表中有什么列?什么是数据类型
desc s_emp

--如何知到我们可以查询那些表?
select
  table_name
from
   tabs;

--选取所有的列
--查找部门表中所有的数据,并且全部显示的列
--练习:查询员工表中的所有的列
select
 *
from
 s_dept


--对数字(日期)列的运算
--查询所有员工,显示last_name,薪水

 --注意运算的优先级别,括号。
 
--对字符列的连接
--将员工的first_name,last_name联合起来显示

--字面量(Literal)的处理
--将员工的first_name,last_name联合起来显示,
--first_name,last_name之间用“-”分割
select
  first_name || '-' || last_name
from
  s_emp;

 --注意:文本,日期类型的字面量加'',数字类型的不用加''。
 --练习将员工的first_name,last_name联合起来显示,
 --first_name,last_name之间用“ ”分割
 
--用别名改善输出(as)
--查询所有员工,显示id,年薪(total)
select
 id, salary * 12 total
from
 s_emp;

 --注意对有特殊字符,关键字,大小写敏感的别名用""处理
 --练习将员工的first_name,last_name联合起来显示,
  --first_name,last_name之间用“ ”分割,输出列名name
  --并且显示年薪(total)
 select
  first_name || ' ' || last_name "name" ,
  salary *12  total
 from
  s_emp

--过滤重复的列
--查询系统中所有部门的部门名称
select
  distinct name
from
  s_dept

--查询系统中有哪几种部门,显示名称
--练习:员工(s_emp)都有那几种title,那几种部门dept_id
select
 distinct title, dept_id
from
 s_emp

 --注意,distinct对后面所有的列有作用
 
---------------------------------------------------------------------------
-- 限制性查询,查询指定的行(符合某种条件的行)
---------------------------------------------------------------------------
--Where
--选取部门标识(dept_id)为42的所有员工,
--显示所有列,
--或只显示员工标识id,last_name
select
  *
from
  s_emp
where
  dept_id = 42

 --注意:where 后面是一个boolean表达式
 --where子句的关键就是构造boolean表达式
 --常用的比较符号>,>=,<,<=,<>,=
 --理解有了where子句后,sql的执行顺序
 
--对文字(日期)列构造条件
--选取last_name 为Magee的员工,
--显示FIRST_NAME  LAST_NAME  TITLE
select
  FIRST_NAME ,LAST_NAME,TITLE
from
  s_emp
where
  last_name = 'magee'


--特殊的比较符号
--选取last_name以“M”为开始的所有员工,显示所有信息
select
  *
from
  s_emp
where
  last_name like 'M%';

select
 table_name
from
 tabs
where
        table_name like 'S/_%' escape '/';

 --模糊查询
 --like与匹配的字符模版%,_
 --补充:escape的作用,
 --显示所有以S_开始的表的表名
 --练习:查询员工(s_emp)表中所有姓名
  --(last_name)中还有“ng"的记录,
  --要求”ng“大小写敏感,显示last_name
 
--null
--用到的表:
 --null_test:用来测试null的属性
 
--null的含义:未知
--查找age为null的数据,显示全部
select
 *
from
 null_test
where
 age is null


--查找age不为null的数据,显示全部
 
 --注意:各种数据类型的列都可以为null
 --null = null,null <> null
 --null进行算数运算后还是null

--逻缉运算符:not,and,or

 


--查询薪资不高于2000的员工,显示last_name,salary,使用not
select
  last_name, salary
from
  s_emp
where
  not (salary > 2000)

 
--查询薪资高于1000,并且部门标识为42的的员工,显示last_name,salary
select
  last_name, salary
from
 s_emp
where
   salary > 1000
   and
   dept_id =42

--查询薪资高于1000,或者部门标识为42的的员工,显示last_name,salary
select
  last_name, salary
from
 s_emp
where
   salary > 1000
   or
   dept_id =42

--分辨下面两个查询的结果记录数目,谁的可能多?
select *
from
 s_emp
where
 ((not salary < 1000)
 and dept_id = 44)
 or dept_id = 42;
 
select *
from
 s_emp
where
 (not salary < 1000)
 and (dept_id=44 or dept_id=42);
 
 --注意优先级别not > and > or
 --使用括号

--特殊的SQL比较符号
--查询薪资在1000与2000之间的员工
select
 *
from
 s_emp
where
 salary >=1000
 and
 salary <= 2000;

select
 *
from
 s_emp
where
 salary between 1000 and 2000;


--查询部门标识是31,35,42,44的部门,显示所有的列
select
 *
from
 s_dept
where
   id = 31
   or id = 35
   or id = 42
   or id = 45;

select
 *
from
 s_dept
where
   id in (31,35,42,45);


 31.5 between 31 and 45
  31.5  in (31,45)

---------------------------------------------------------------------------
--  排序
---------------------------------------------------------------------------
--order by
--查询所有的员工,按照薪资从低倒高排序,
--显示last_name,salary
select
  last_name, salary
from
  s_emp
order by
  salary asc

 --注意Order by的位置
 --理解有了order by子句后,sql的执行顺序

--order by子句中的列与select子句中的列的关系
--查询所有的员工,按照薪资从低倒高排序,显示last_name
select
  last_name name
from
  s_emp
order by
  salary


 --注意特例: order by 数字:order by 2
 --注意特例: order by 别名:order by name
 
--查询所有的员工,按照薪资从高倒低排序,
--显示last_name,salary
select
  last_name, salary
from
 s_emp
order by
        salary desc

 --注意两种命令:SQL命令与iSQL*PLUS
 --iSQL*PLUS:desc,list
 --SQL关键字:desc,asc
 
--查询所有的员工,
--显示last_name,dept_id,salary按照部门从低倒高排序,
--同样部门薪资从低倒高排序。
select
  last_name, dept_id, salary
from
  s_emp
order by
  dept_id,salary 

 --多列排序

--判断下面语句的执行结果
select
  last_name, dept_id, salary
from
  s_emp
order by
  dept_id , salary desc

--对有null值的order by
--测试null_test
 
---------------------------------------------------------------------------
--  函数 1
---------------------------------------------------------------------------
--函数的定义:有输入参数,有返回值
--函数类型:通用函数,字符处理函数,数字处理函数,日期处理函数,类型转换函数
--通用函数
--查询系统当前登陆用户
 
 --dual:系统表,哑表
 
--查询所有员工,显示LAST_NAME,COMMISSION_PCT,要求COMMISSION_PCT为空的显示0


--字符处理函数
 --lower,upper,initcap
 --concat,substr,instr,length,trim

select LOWER('SQL Course') from dual;
select UPPER('SQL Course') from dual;
select INITCAP('SQL Course') from dual;
select CONCAT('Good','String') from dual;
select SUBSTR('String',2,3) from dual;
select INSTR('hello','e') from dual;
select LENGTH('String') from dual;
select trim('   String   ') from dual;

--数字处理函数
 -- round,trunc
 --mod
select ROUND(45.923,2) from dual;
select ROUND(45.923,0) from dual;
select ROUND(45.923,-1) from dual;

select TRUNC(45.923,2) from dual;
select TRUNC(45.923,0) from dual;
select TRUNC(45.923,-1) from dual;

select MOD(1600,300) from dual;

--日期处理函数 
--查询所有的emp,显示LAST_NAME, START_DAT

 --日期在Oracle数据库中存储为数字,
 --存储的内容是世纪,年,月,日,小时,分钟,秒
 --日期的默认显示格式
 --日期可以进行加减运算,单位是天
 --考虑加一个小时如何操作
 
--日期函数:sysdate,months_between,add_months,next_day,last_day
--日期函数 ROUND,TRUNC
select MONTHS_BETWEEN(sysdate,sysdate-188) from dual;
select ADD_MONTHS(sysdate,2) from dual;
select NEXT_DAY(sysdate,6) from dual;
select LAST_DAY(sysdate) from dual;

select ROUND(SYSDATE) from dual;
select TRUNC(SYSDATE) from dual;

--类型转换函数
 --数字 - 文本:to_char,to_number
select TO_CHAR(12345.237,'9,999,999.99') from dual;
select TO_CHAR(12345,'$9,999,999.99') from dual;
select TO_CHAR(21,'00000') from dual;

select TO_NUMBER('$12,345','$9,999,999') from dual;

 --日期 - 文本: to_char, to_date
 --查询现在的时间,按照格式yyyy-mm-dd hh24:mi:ss 显示
 select
    to_char(sysdate,'yyyy-mm-dd hh24:mi:ss')
  from
    dual;
---------------------------------------------------------------------------
-- 函数2
---------------------------------------------------------------------------
--查询员工的总数

--查询员工的最高,最低,平均薪资,以及薪资的总和
select
  max(salary),min(salary), avg(salary),sum(salary)
from
 s_emp

 --多行函数,单行函数,差别在输入上
 --常见的count,sum,avg,max,min.....
 --练习,查找员工中最大的last_name
 --文本,日期也可以比较大小

--在null_test中查找出平均age
 
 --注意对null的处理
 --注意count(*),与count(age)的不同
 
--用到的表test:用来测试sum(distinct)
--猜测下面的执行结果
select AVG(salary)
from test;

select AVG(DISTINCT salary)
from test;

--猜测下面的语句是否能够运行
select last_name, avg(salary)
from s_emp;

 --注意,select语句中,分组函数不能同时与普通列(或单行函数)同时出现

---------------------------------------------------------------------------
-- 分组
---------------------------------------------------------------------------
--按照部门分组,查询每个部门的  薪资总和,
--显示部门编号,薪资总和
select
  sum(salary)
from
  s_emp
group by
  dept_id;

 --理解有了group by之后sql执行的顺序

--猜测下面的语句是否能够运行
select dept_id, last_name, avg(salary)
from s_emp
gourp by dept_id;
 --注意,select子句中,分组函数不能同时与
  --除分组列之外的普通列(或单行函数)同时出现
 --注意,有group by 之后select语句中只能出现,分组函数 + 分组列
 --练习:查询每个部门编号,薪资总和,平均薪资,最高薪资,最低薪资,人数,并按照薪资总和逆序显示
 
 --理解select, from , where , group by, order by 的执行顺序

 --注意,order by子句中,分组函数不能同时与除分组列之外的普通列(或单行函数)同时出现
 
--查询每个部门,每种头衔(title)的平均薪资。
select
  avg(salary),dept_id, title
from
  s_emp
group by
  dept_id, title

 --按照多列分组
---------------------------------------------------------------------------
-- 对组的过滤
---------------------------------------------------------------------------
--查询平均薪资高于1200的部门,显示其部门ID,薪资总和
select
 dept_id, sum(salary)
from
 s_emp
group by
 dept_id
having
 avg(salary) >1200

 --注意having的执行的时间

--将薪资高于800的员工按照部门分组,
--查询平均薪资高于1200的部门,显示其部门ID,薪资总和
select
 dept_id, sum(salary)
from
 s_emp
where
 salary > 800
group by
 dept_id
having
 avg(salary) > 1200

 --区分where与having的异同
  --同:都是过滤
  --异:where:分组前
  --异:having:分组后

--练习:将薪资高于1000的员工按照部门分组,
 --查询记录数多于2的部门,
 --按照薪资总和降序显示部门id,平均薪资。
 select
  dept_id, avg(salary)
 from
  s_emp
 where
  salary > 1000
 group by
  dept_id
 having
  count(*) > 2
 order by
  sum(salary) desc

 --理解:select, from, where, gourp by , having , order by执行的顺序
 --理解每个子句中可以出现的内容。
  
---------------------------------------------------------------------------
-- 多表连接查询
---------------------------------------------------------------------------
--用到的表
 --emp:简易员工数据
 --dept:简易部门数据
 
 
--显示员工姓名(name),以及员工所在部门的名称(name)
 select
    emp.name,  dept.name
 from
    emp e, dept d
  where
    emp.dept_id = dept.id
    and
    emp.salary >1000
    or ....

 select
  emp.name, dept.name
  from
    emp join dept
      on emp.dept_id =  dept.id
   where
      emp.salary  > 1000

 --理解:from后面多个表时的执行顺序
 --理解:where中关联条件的作用,知到笛卡尔查询的含义
 --理解:关系型数据库中的关系的含义
 --了解:SQL99的写法 inner join,“内连接”的名称来源
 --理解多表关联时sql语句执行的顺序,以及如何在多表中查询数据
 --注意:列前加表名
 --注意:可以在from 子句中表的别名(as),表加别名后,在其他子句中只能使用别名
 
--用到的表:
 --s_ord: 定单表
 --s_item:定单明细表
 --s_customer:客户信息表
 --s_product:产品信息表
 
 --注意其中的关系列
 --练习:查询定单编号,以及定单对应的明细编号
 
 --练习:查询客户编号,以及客户对应的定单编号,
  --以及定单对应的明细编号
 
--查询全部的员工(表:emp),显示员工的姓名(name),
--以及员工对应部门(dept)的名称(name)
select
 e.name emp_name, d.name dept_name
from
 emp e, dept d
where
 e.dept_id = d.id

select
 e.name emp_name, d.name dept_name
from
 emp e join dept d
 on
 e.dept_id = d.id

 --注意:外连接的含义:以其中的两张表中的一张为基准,另一张表中能有连接的连接上,没有的补上空
 --外连接分:左外连接,右外连接,全外连接
 --了解SQL99的写法
 
--查询员工(emp),显示员工的姓名(name),以及员工的主管的姓名(name)

 --自连接:利用别名将一张表变为逻缉上的两张表
 --练习:查询所有员工(emp),显示员工的姓名(name),以及员工的下属的姓名(name)
 
--小结
--以上的连接均(内连接,外连接)有一个特点:基于表间关系的连接
--下面的查询不是基于关系列的查询
--用到的表:
 --person:存放所有的人员信息
 --server_a:存放a类服务的相关信息
 --server_b:存放b类服务的相关信息

--查询可以享受server_a中各种服务的人员,显示人员的姓名,享受的服务的名称
 
--查询可以享受server_b中各种服务的人员,显示人员的姓名,享受的服务的名称


 --以上的没有使用=为连接的两表条件的查询被称为不等连接,通常是基于非关系列的。

---------------------------------------------------------------------------
-- 子查询
---------------------------------------------------------------------------
--在s_emp中查找姓名(last_name)为Smith的员工的title
  select
     title
  from
    s_emp
  where last_name = 'Smith';


--查找title为Stock Clerk的员工的姓名
select
  last_name
from
  s_emp
where
  title =  'Stock Clerk'

 

--查询与Smith同样title的人,显示其姓名。
select
  last_name
from
   s_emp
where
   title = (
     select title
     from s_emp
     where last_name = 'Smith'
     )


 --子查询:嵌套查询,就是查询中的查询
 --理解目前这种子查询的执行的过程
 --子查询可以出现的位置,from 子句,
 --where 子句, having子句
 --子查询可以是学过的所有查询
 --子查询可以嵌套子查询
 --练习:查询与Smith同样部门的人,显示其姓名
       select
   last_name
       from
          s_emp
        where
    dept_id = (
      select dept_id from s_emp
      where last_name = 'Smith'
    )


 --练习:查询与部门名称是Finance的人,
 --显示其姓名,(用子查询)
 select
   e.last_name name
 from
    s_emp e join s_dept d
      on e.dept_id = d.id
 where
    d.name = 'Finance'

 select
   last_name name
 from
   s_emp
 where
   dept_id = (
     select id from s_dept
     where name = 'Finance'
   )

 

--查询与部门名称是Sales的人,显示其姓名,(用子查询) 
 select
   last_name name
 from
   s_emp
 where
   dept_id = (
     select id from s_dept
     where name = 'Sales'
   )

 --根据返回结果集的数量,子查询分:
  --单行子查询
  --多行子查询
  --子查询查询的表不一定要与外围查询查询的表一致
  
--练习:查询薪资高于所有员工平均薪资员工,
 --显示其姓名,薪资
 select
          last_name, salary
 from
    s_emp
  where
     salary > (
        select avg(salary) from s_emp
     )


--查询所有薪资高于其所在部门平均薪资员工,
--显示其姓名,薪资
 select
          last_name, salary
 from
    s_emp e1
  where
     salary > (
        select avg(salary) from s_emp e2
        where e1.dept_id = e2.dept_id
     )

 --非相关子查询:内查询可以直接执行,不需要外查询的支持
 --相关子查询:内查询不能直接执行,需要外查询支持
 --了解相关子查询的执行顺序
 
--rownum

--伪列:表中没有真正存在的列,但可以像列一样使用在sql语句中
 --rownum,rowid....
 
--查询所有的员工,显示id,last_name,salary,显示前3条记录

--查询所有的员工,显示id,last_name,salary,显示第3条记录  (或显示第3条以后记录 )

 --理解rownum产生的原理
 
--查询所有的员工,按照薪资由高到低,
--显示id,last_name,salary,显示前3条记录
select
   salary, last_name,id
from
  ( select  salary, last_name,id
    from s_emp
    order by salary
  )
where
  rownum <= 3

 --一般在子查询中不使用order by子句
 --以上这种查询被称为Top-N查询
 
--查询所有的员工,显示id,last_name,salary,显示第3条记录  (或显示第3条以后记录 )


--查询所有的员工,显示id,last_name,salary,显示第3条到第5条记录 

 --基于Oracle的的翻页的实现的一种解决方案
select
  id,last_name,salary
from
  (select rownum rn ,id,last_name,salary
  from
    ( select id,last_name,salary
      from s_emp
      order by salary
    )
  where rownum < = 20 
)
where
  rownum >= 10 


--小结
--DQL:数据查询语言
--单表查询:
 --对指定列的选择
 --对指定行的选择
 --排序
 --分组
 --分组后的过滤
 --sql函数
 --单表查询的核心,理解查询执行的过程

--多表查询
 --解决的基本方案:利用各种连接手段将多张表连接成一张逻缉上的表,从而将多表查询变为单表查询
 --针对连接手段的常用的分类
  --内连接
  --外连接
  --自连接
  --不等连接

--子查询
 --子查询出现的位置
 --根据子查询返回的结果的数量,分为
  --单行子查询
  --多行子查询
 --根据内查询的执行是否依赖于外查询的支持,分为
  --非相关子查询
  --相关子查询
 --rownum与翻页
 
---------------------------------------------------------------------------
--  创建表
---------------------------------------------------------------------------
--创建一张表 shenyu_emp,可以存放标识符id(数字)
create table shenyu_emp (
 id number
)

--删除表shenyu_emp
drop table shenyu_emp;

--创建一张表 shenyu_emp,
 --可以存放标识符id(数字),
 --姓名name(文本),
 --登陆日期login_date(日期类型)

create table shenyu_emp(
 id number,
 name varchar2(20),
 login_date date
);

--删除表shenyu_emp
drop table shenyu_emp;

--数据类型
--数字类型
  number(m,n) :(5,2) 
  number = number(38,0) = number(38)
 
--字符类型
char(5)
varchar2(5)

 --分辨char,varchar2的不同,与好坏


--日期类型
 --Oracle 的日期为date,还有timestamp
 
--创建带有默认值的列
--创建一张表 shenyu_emp,可以存放标识符id(数字),
--姓名name(文本),
--登陆日期login_date(日期类型)
--登陆日期的默认值为插入记录的时间
drop table shenyu_emp;
create table shenyu_emp(
 id number,
 name varchar2(20),
 login_date date default sysdate
);
 --理解默认值的含义
 
--使用子查询创建表
--备份s_emp表中,
--薪资高于1000元的员工的
--id,last_name,salary,
--存放在s_emp_bck表中,列名为(id,name,salary)
drop table s_emp_bck;
create table s_emp_bck
as
select id, last_name name, salary
from s_emp
where salary > 1000;


---------------------------------------------------------------------------
-- 对记录进行增删改
---------------------------------------------------------------------------
--向shenyu_emp表中新增一条数据
--id=1,name=tarena,login_date=当前日期
insert into shenyu_emp ( name, login_date, id)
values ('tarena',sysdate, 1);

--练习向shenyu_emp表中新增一条数据
 --id=2,name=test,login_date=1999.10.20 18:30:05

insert into shenyu_emp (id, name, login_date)
values (2,'test',
to_date('1999-10-20 18:30:05','yyyy-mm-dd hh24:mi:ss'));

--向shenyu_emp表中新增一条数据id=3
insert into shenyu_emp(id) values(3);
insert into shenyu_emp(id, name, login_dat)
values (4,null,null);

 --插入时,表达“空”的方式
 --理解默认值的作用
 --掌握插入时指定列的方法
 
--将shenyu_emp 中所有记录的login_date
 --变为2000.10.20 18:30:05
 update shenyu_emp
 set login_date =
 to_date('2000-10-20 18:30:05','yyyy-mm-dd hh24:mi:ss');

--将shenyu_emp 中标识(id)为2的记录的name更新成hello,
 --login_date变为当前时间
update shenyu_emp
set name='hello',
    login_date = sysdate
where
   id = 2;

--练习修改shenyu_emp,
 --将shenyu_emp 中标识(id)为1的记录
 --的login_date提前15天
update shenyu_emp
set login_date = login_date -15
where id = 1

--删除shenyu_emp表中,用名字以't'开始的所有记录
delete from shenyu_emp
where name like 't%'


--删除所有shenyu_emp表中的数据。
delete from shenyu_emp;

--利用子查询insert ,update, delete

--将s_emp中所有薪资高于1000元的员工的id,last_name,
--存放在shenyu_emp中。
insert into shenyu_emp (id, name)
(select id, last_name from s_emp where salary > 1000)

--将shen_emp表中login_date 更新为
--在s_emp表中同样标识(id)记录中的START_DATE字段。
update shenyu_emp e1
set login_date =
(select start_date from s_emp e2 where e1.id = e2.id )

--练习:删除shenyu_emp表中,
--所有login_date 早于 'Smith' 的login_date的所有记录
delete from shenyu_emp
where login_date < (
 select login_date from
 shenyu_emp where name = 'Smith'
)

---------------------------------------------------------------------------
-- 对表的改
---------------------------------------------------------------------------
--增加列
--向shenyu_emp中添加一列dept_id number
alter table shenyu_emp
   add dept_id number;

--向shenyu_emp中添加一列salary number(6,2) default 100
alter table shenyu_emp
   add salary number(6,2) default 100

--删除列
--将shenyu_emp表中的dept_id列去掉
alter table shenyu_emp
  drop column dept_id;

--修改列
--修改列的宽度
--将shenyu_emp表中的salary 的类型变为number(8,2)
alter table shenyu_emp
   modify salary number(8,2);

alter table shenyu_emp
   modify salary number(7,2)

 --注意将列的宽度减小时的限制
 
--将shenyu_emp表中的salary 的默认值去掉
alter table shenyu_emp
  modify salary default null
 --注意:默认值去掉,或修改,只会影响到以后的插入的数据,不会影响之前已经存在的数据
 
 --练习:用已经学过的知识,
 --将shenyu_emp中的salary改名为max_salary
 alter table shenyu_emp
    add max_salary number(8,2);
 
 update shenyu_emp
    set max_salary = salary;
 
 alter table shenyu_emp
    drop column salary;

--修改表的名称
--将shenyu_emp改名为shenyu_emp_bck
rename shenyu_emp to shenyu_emp_bck

--截断表
--将shenyu_emp_bck 截断
truncate table shenyu_emp_bck;

---------------------------------------------------------------------------
--  数据库建模
---------------------------------------------------------------------------
--在数据库中存储以下信息:
--员工:姓名,年龄(name),编号(code),薪资(salary),

 --注意:
  --一定要有一列作为标识列
 --标识列的特征:
  --非空,唯一

--数据库中还可以存储员工:姓名,年龄(name),编号(code),薪资(salary)
  --每种属性一个列 
  
--练习:在数据库中存储以下信息
--部门:名称(name),编号(code)

 --每种实体存储在自己的表中


--要求:一个员工可以兼职多个部门,每个部门可以有多个员工,
--在数据库中存储以上的关联关系

 --实体与实体的代表ID,注意:ID具有不变性
  --业务标识
  --真正的标识,不含任何业务逻缉
  
 --关系之间的数量之比叫做阶数
 --关系性数据库不但可以存储数据,
 --还可以存储数据之间的关系

 --many-to-many
 --数据库实体之间的关系没有方向性

--要求:一个员工可以一个部门,每个部门可以有多个员工,
--在数据库中存储以上的关联关系

 --many-to-one
  --两种解决方案
  --注意:数据库实体之间的关系没有方向性
  
--思考:存储many-to-many这种关系能否采
--用在两方各加一列来解决?

--练习:
 --要求在数据库中存储学生信息:记录姓名
 --要求在数据库中存储课程信息:记录名称
 --要求在数据库中学生可以选择多门课程,每门课程可以有多个学生上
 --要求在数据库记录某个学生,某个课程的成绩
  --注意:目前的应用中不使用联合标识。


--要求:一个员工可以一个部门,每个部门可以有一个员工,
--在数据库中存储以上的关联关系

 --one-to-one
  --三种解决方案
  
--要求:员工还可以存储:生日,地址,性别,邮件,开发技能

 --表太大,而且不是每次都要访问所有信息时可以考虑将一个实体拆分到不同表中存储,这时候通常可以采用公用标识符来表达one-to-one
 
---------------------------------------------------------------------------
--  约束
---------------------------------------------------------------------------
--非空约束
--要求在建表时,指定员工的code不能为空。

--要求在部门表建好后添加约束,限制code不能为空

--唯一约束
--要求在建立表的时候,指定员工的code非空,且唯一

--要求在部门表建好后添加约束,限制code唯一

--主键约束
--要求在建立表的时候,指定员工的标识符非空,且唯一

--外键约束
--要求可以实现一个部门存储多个员工,一个员工只能在一个部门
--并且要求员工的部门必须是实际存在的部门,并且部门中有员工时,不容许删除部门

 --如果其他要求不变,而要求如果部门中有员工时,删除部门时,将里面的用户也一并删除
 --注意,外键指向的列必须是唯一的。

--其他约束:check

--删除约束

--关闭约束

--打开约束


--删除表时顺便将指向它的约束删除

--注意:
 --约束只对DML,部分DDL其作用,对DQL不起作用。
 --约束 <> 关系,虽然约束通常加在关系列上。

---------------------------------------------------------------------------
--  数据库建模
---------------------------------------------------------------------------
--用户信息:
-- 登陆名,登陆口令,  真实名, 性别,地址,出生日期

--产品信息:
-- 产品编号,名称,价格,产品描述

--定单信息:
-- 定单编号,用户姓名,送货地址,送货日期,金额总计
 
-- 定单明细:
-- 产品名称, 产品价格, 订货数量, 价格小计

--用户必须有登陆名,且唯一
--产品必须有编号,且唯一
--定单必须有编号,且唯一


--用户可以有多个定单
--定单可以有多条明细
--明细可以单独访问

--假设:
 --产品信息录入系统之后,不再进行修改。
 --用户信息录入系统之后,不再进行修改。

--数据库建模的过程
  --实体模型:与客户沟通的工具
   --明确实体
   --明确实体之间的结束关系
   
  --
   --确定表
   --确定列
   --确定各种约束(主键,外键,唯一,非空)
   
  --建立其他数据库对象
   --什么对象?
  
  --生成脚本

 
 

原创粉丝点击