zoukankan      html  css  js  c++  java
  • MSSQL → 02:数据库结构

    一、数据库的组成

      在SQL Server 2008中,用户如何访问及使用数据库,就需要正确了解数据库中所有对象及其设置。数据库就像一个容器,它里面除了存放着数据的表之外,还有视图、存储过程、触发器、约束等数据库对象。数据库管理的核心任务包括创建、操作和维护数据库。

    二、数据库文件及其文件组

      数据库的存储结构分为逻辑存储结构和物理存储结构。

    • 逻辑存储结构:说明数据库是由哪些性质的信息所组成。SQL Server的数据库不仅仅只是数据的存储,所有与数据处理操作相关的信息都存储在数据库中。
    • 物理存储结构:数据库在磁盘上是以文件为单位存储的,由数据库文件和事务日志文件组成,一个数据库至少应该包含一个数据库文件和一个事务日志文件。

      SQL Server数据库系统中的数据库文件是由数据文件和日志文件组成的,数据文件以盘区为单位存储在存储器中。

    2.1、数据文件

      数据库文件是指数据库中用来存放数据库数据和数据库对象的文件,一个数据库可以有一个或多个数据库文件,一个数据库文件只能属于一个数据库。当有多个数据库文件时,有一个文件被定为主数据文件,用来存储数据库的启动信息和部分或全部数据,一个数据库只能有一个主数据库文件。数据文件则划分为不同的页面和区域,页是SQL Server存储数据的基本单位。

    • 主数据文件:是数据库的起点,指向数据库文件的其他部分,每个数据库都有一个主要数据文件,扩展名为.mdf。
    • 次数据文件:包含除主数据库文件之外的所有数据文件,一个数据库可以没有次数据文件,也可以有多个次数据文件,扩展名为.ndf。
    • 事务日志文件:包含恢复数据库所有事务日志的信息。每个数据库必须至少有一个事务日志文件,当然也可以有多个,事务日志文件的推荐文件扩展名是.ldf
    • 文件流( Filestream):可以使得基于 SQLServer的应用程序能在文件系统中存储非结构化的数据,如文档、图片、音频等,文件流主要将SQLServer数据库引擎和新技术文件系统(NTFS)集成在一起,它主要以varbinary (max)数据类型存储数据。

    2.2、日志文件

      SQL Server的日志是由一系列日志记录组成,日志文件中记录了存储数据库的更新情况等事务日志信息,用户对数据库进行的插入、删除和更新等操作都会记录在日志文件中。当数据库损坏时,可以根据日志文件来分析出错的原因,或者数据丢失时,还可以使用事务日志恢复数据库。每一个数据库至少必须拥有一个事务日志文件,而且允许拥有多个日志文件。
      SQL Server2012不强制使用.mdf、.ndf或者.ldf作为文件的扩展名,但建议使用这些扩展名帮助标准文件的用途。数据库中的所有文件的位置都记录在master数据库和该数据库在主数据文件中。

    三、数据库的分类

    3.1、系统数据库:由系统服务提供

      SQLServer系统数据库分别是:master、model、tempdb、msdb数据库。

      3.1.1、master数据库

      master是SQL Server中最重要的数据库,是整个数据库服务器的核心。用户不能直接修改master数据库,如果master数据库损坏了,那么整个SQL Server服务器将不能工作。
      master数据库中包含了以下的一些内容:

    • 所有用户的登录信息
    • 用户所在的组
    • 所有系统的配置选项
    • 服务器中本地数据库的名称和信息
    • SQL Server的初始化方式等

      master数据库保存系统表用于系统的总体控制。如在新建一个数据库时,在master数据库的sysdatabases表中插入对应的记录。
      作为一个数据库管理员,应该定期备份master数据库。

      3.1.2、model数据库

      model数据库是SQL Server中创建数据库的模板,如果用户

    • 希望创建的数据库有相同的初始化文件大小,则可以在model数据库中保存文件大小的信息;
    • 希望所有的数据库中都有相同的一个或多个表,可以将该数据表保存在model数据库中

      新创建的数据库以model数据库中的数据作为模板,因此在修改model数据库之前要考虑到,任何对model数据库中数据的修改都要影响到所有使用该模板创建的数据库。
      由于model数据库作为其他任意数据库的模板,系统中必须保留,不能删除。
      在更改model数据库时需要注意:任意新建的数据库至少要比model数据库大。如果将model数据库大小更改为100MB,则不能创建小于100MB的数据库。

      3.1.3、tempdb数据库

      msdb提供了运行SQL Server Agent工作的信息。SQL Server Agent是SQL Server中的一个Windows服务,该服务用来运行制定的计划任务。如在计划对一个数据库每夜进行备份时,则在msdb数据库中有一个相应的记录项。

      3.1.4、msdb数据库

      tempdb是SQL Server中的一个临时数据库,用于存放临时对象或中间结果,只要创建临时表,则临时表会创建在tempdb数据库中。SQL Server关闭后,该数据库中的内容被清空,每次重新启动服务器之后,tempdb数据库将被完全重建。

      Tempdb数据库保存系统运行过程中产生的临时表和存储过程。当然,它还满足其他的临时存储要求,比如保存SQL Server生成的存储表等。Tempdb数据库是一个全局咨询,任何连接到系统的用户都可以在该数据中产生临时表和存储过程。Tempdb数据库在每次SQL Server启动的时候,都会清空该数据库中的内容,所以每次启动SQL Server后,该表都是干净的。临时表和存储过程在连接断开后会自动除去,而且当系统关闭后不会有任何活动连接,因此,Tempdb数据库中没有任何内容会从SQL Server的一个会话保存到另一个会话中。
      默认情况下,在SQL Server在运行时Tempdb数据库会根据需要自动增长。不过,与其它数据库不同,每次启动数据库引擎时,它会重置为其初始大小。如果为Tempdb数据库定义的大小较小,则每次重新启动SQL Server时,将Tempdb数据库的大小自动增加到支持工作负荷所需的大小这一工作可能会成为系统处理负荷的一部分。为避免这种开销,可已使用ALTER DATABASE 增加Tempdb数据库的大小。

    3.2、用户数据库:用户或程序员创建的数据库

    四、创建数据库用户及授权

    • 使用SSMS图形界面创建数据库

       ①、打开安全性--登录名,右键 新建用户

      

      ②、此时会出现Windows和SQL server身份验证

      ③、此时先选择Windows身份登录,点击 搜索,则弹出 选择用户和组的弹出框,在其中输入Windows系统中的用户

      

     

      ④、打开 控制面板--选择用户账户--管理其他账户---选择一个新账户,此时选择fww用户

      

      ⑤、在输入框中写入fww,点击 检查名称,则自动加入了全名

       ⑥、则在登录名中自动代入了Windows用户,点击确定,则用户添加成功。

      

      ⑦、断开此时的连接

      ⑧、新建fww对应的连接,但是此时账户默认为Administrator,且为灰色,无法更改

      

      ⑨、按Alt+ Ctrl+Delete键,切换用户

      

      ⑩、则Sqlserver的登录账户则变为BalmyLee

      

      ⑪、输入账户信息,则用户登录成功。

    • 使用Transact-SQL 语句创建用户

      ①、首先在 SQL Server 服务器级别,创建登陆帐户(create login)

      语法:

    CREATE LOGIN 用户名 PASSWORD='密码' DEFAULT_DATABASE=数据库;

      示例:

    --创建登陆帐户(create login)
    create login dba with password='abcd1234@', default_database=LibraryDB;

      ②、创建数据库用户(create user)

      语法:

    CREATE USER 用户名 FOR LOGIN 登录用户名 WITH DEFAULT_SCHEMA=数据库;

      示例:

    --为登陆账户创建数据库用户(create user),在mydb数据库中的security中的user下可以找到新创建的dba
    create user dba for login dba with default_schema=LibraryDB

      并指定数据库用户“dba” 的默认 schema 是“LibraryDB”。这意味着 用户“LibraryDB” 在执行“select * from t”,实际上执行的是 “select * from LibraryDB.t”。

    ③、通过加入数据库角色,赋予数据库用户“dba”权限

    语法:

     

    格式:

    --通过加入数据库角色,赋予数据库用户“db_owner”权限
    exec sp_addrolemember 'db_owner', 'dba'

    此时,dba 就可以全权管理数据库 mydb 中的对象了。
    如果想让 SQL Server 登陆帐户“dba”访问多个数据库,比如 mydb2。 可以让 sa 执行下面的语句:

    --让 SQL Server 登陆帐户“dba”访问多个数据库
    use mydb2
    go
    create user dba for login dba with default_schema=dbo
    go
    exec sp_addrolemember 'db_owner', 'dba'
    go

      此时,dba 就可以有两个数据库 mydb, mydb2 的管理权限了!

      ④、完整的代码示例

    --创建数据库mydb和mydb2
    
    --在mydb和mydb2中创建测试表,默认是dbo这个schema
    CREATE TABLE DEPT
           (DEPTNO int primary key,
            DNAME VARCHAR(14),
            LOC VARCHAR(13) );
    
    --插入数据
    INSERT INTO DEPT VALUES (101, 'ACCOUNTING', 'NEW YORK');
    INSERT INTO DEPT VALUES (201, 'RESEARCH',   'DALLAS');
    INSERT INTO DEPT VALUES (301, 'SALES',      'CHICAGO');
    INSERT INTO DEPT VALUES (401, 'OPERATIONS', 'BOSTON');
    
    
    --查看数据库schema, user 的存储过程
    select * from sys.database_principals
    select * from sys.schemas 
    select * from sys.server_principals
    
    --创建登陆帐户(create login)
    create login dba with password='abcd1234@', default_database=mydb
    
    --为登陆账户创建数据库用户(create user),在mydb数据库中的security中的user下可以找到新创建的dba
    create user dba for login dba with default_schema=dbo
    
    --通过加入数据库角色,赋予数据库用户“db_owner”权限
    exec sp_addrolemember 'db_owner', 'dba'
    
    --让 SQL Server 登陆帐户“dba”访问多个数据库
    use mydb2
    go
    create user dba for login dba with default_schema=dbo
    go
    exec sp_addrolemember 'db_owner', 'dba'
    go
    
    --禁用登陆帐户
    alter login dba disable
    --启用登陆帐户
    alter login dba enable
    
    --登陆帐户改名
    alter login dba with name=dba_tom
    
    --登陆帐户改密码: 
    alter login dba with password='aabb@ccdd'
    
    --数据库用户改名: 
    alter user dba with name=dba_tom
    
    --更改数据库用户 defult_schema: 
    alter user dba with default_schema=sales
    
    --删除数据库用户: 
    drop user dba
    
    --删除 SQL Server登陆帐户: 
    drop login dba
    • 使用存储过程创建用户

      下面一个实例来说明在sqlserver中如何使用存储过程创建角色,重建登录,以及如何为登录授权等

    /*--示例说明
            示例在数据库InsideTSQL2008中创建一个拥有表HR.Employees的所有权限、拥有表Sales.Orders的SELECT权限的角色r_test
        随后创建了一个登录l_test,然后在数据库InsideTSQL2008中为登录l_test创建了用户账户u_test
        同时将用户账户u_test添加到角色r_test中,使其通过权限继承获取了与角色r_test一样的权限
        最后使用DENY语句拒绝了用户账户u_test对表HR.Employees的SELECT权限。
        经过这样的处理,使用l_test登录SQL Server实例后,它只具有表Sales.Orders的select权限和对表HR.Employees出select外的所有权限。
    --*/
    
    
    USE InsideTSQL2008
    
    --创建角色 r_test
    EXEC sp_addrole 'r_test'
    
    --添加登录 l_test,设置密码为pwd,默认数据库为pubs
    EXEC sp_addlogin 'l_test','a@cd123','InsideTSQL2008'
    
    --为登录 l_test 在数据库 pubs 中添加安全账户 u_test
    EXEC sp_grantdbaccess 'l_test','u_test'
    
    --添加 u_test 为角色 r_test 的成员
    EXEC sp_addrolemember 'r_test','u_test'
    
    
    --用l_test登陆,发现在SSMS中找不到仍和表,因此执行下述两条语句出错。
    select * from Sales.Orders
    select * from HR.Employees
    
    --授予角色 r_test 对 HR.Employees 表的所有权限
    GRANT ALL ON HR.Employees TO r_test
    --The ALL permission is deprecated and maintained only for compatibility. 
    --It DOES NOT imply ALL permissions defined on the entity.
    --ALL 权限已不再推荐使用,并且只保留用于兼容性目的。它并不表示对实体定义了 ALL 权限。
    
    --测试可以查询表HR.Employees,但是Sales.Orders无法查询
    select * from HR.Employees
    
    
    --如果要收回权限,可以使用如下语句。(可选择执行)
    revoke all on HR.Employees from r_test
    --ALL 权限已不再推荐使用,并且只保留用于兼容性目的。它并不表示对实体定义了 ALL 权限。
    
    
    --授予角色 r_test 对 Sales.Orders 表的 SELECT 权限
    GRANT SELECT ON Sales.Orders TO r_test
    
    --用l_test登陆,发现可以查询Sales.Orders和HR.Employees两张表
    select * from Sales.Orders
    select * from HR.Employees
    
    --拒绝安全账户 u_test 对 HR.Employees 表的 SELECT 权限
    DENY SELECT ON HR.Employees TO u_test
    
    --再次执行查询HR.Employees表的语句,提示:拒绝了对对象 'Employees' (数据库 'InsideTSQL2008',架构 'HR')的 SELECT 权限。
    select * from HR.Employees
    
    --重新授权
    GRANT SELECT ON HR.Employees TO u_test
    
    --再次查询,可以查询出结果。
    select * from HR.Employees
    
    
    USE InsideTSQL2008
    --从数据库中删除安全账户,failed
    EXEC sp_revokedbaccess 'u_test'
    --删除角色 r_test,failed
    EXEC sp_droprole 'r_test'
    --删除登录 l_test,success
    EXEC sp_droplogin 'l_test'

    revoke 与 deny的区别

    revoke:收回之前被授予的权限
    deny:拒绝给当前数据库内的安全帐户授予权限并防止安全帐户通过其组或角色成员资格继承权限。比如UserA所在的角色组有inset权限,但是我们Deny UserA使其没有insert权限,那么以后即使UserA再怎么到其他含有Insert的角色组中去,还是没有insert权限,除非该用户被显示授权。
    简单来说,deny就是将来都不许给,revoke就是收回已经给予的。

    示例:

    GRANT INSERT ON TableA TO RoleA
    GO
    EXEC sp_addrolemember RoleA, 'UserA' -- 用户UserA将有TableA的INSERT权限
    GO
    
    REVOKE INSERT ON TableA FROM RoleA -- 用户UserA将没有TableA的INSERT权限,收回权限
    GO
    
    GRANT INSERT ON TableA TORoleA --重新给RoleA以TableA的INSERT权限
    GO 
    
    DENY INSERT ON TableA TO UserA -- 虽然用户UserA所在RoleA有TableA的INSERT权限,但UserA本身被DENY了,所以用户UserA将没有TableA的INSERT权限。

     

  • 相关阅读:
    [LeetCode]Surrounded Regions
    生产者消费者问题
    多线程试题汇总
    Linux多线程编程
    运算符优先级表
    正向代理和反向代理
    遗传算法
    嵌入式培训学习历程第十五天
    嵌入式培训学习历程第十四天
    一个猜数的游戏
  • 原文地址:https://www.cnblogs.com/BalmyLee/p/10945979.html
Copyright © 2011-2022 走看看