全书笔记
mhsj (活着不是目的,好好活着才是。)
在读 SQL必知必会(第3版)
- 章节名:全书笔记
第1章 了解SQL 【数据库】保存有组织的数据的容器(通常是一个文件或一组文件)。 【表】某种特定类型数据的结构化清单。 在相同数据库中不能两次使用相同的表名,但在不同的数据库中却可以使用相同的表名。 【模式】关于数据库和表的布局及特性的信息。 【列】表中的一个字段。所有表都是由一个或多个列组成的。 【数据类型】所容许的数据的类型。每个表列都有相应的数据类型,它限制该列中存储的数据。 【行】表中的一条记录。 【主键】一列(或一组列),其值能够唯一标识表中的每一行。 表中的任何列都可以作为主键,只要它满足以下条件: 任意两行都不具有相同的主键值; 每个行都必须具有一个主键值(不允许NULL值); 主键列中的值不允许修改或更新; 主键值不能重用。 也可以一起使用多个列作为主键。在使用多列作为主键时,上述条件必须应用到构成主键的所有列,所有列值的组合必须时唯一的(但单个列的值可以不唯一)。 【SQL】是结构化查询语言。一种专门用来与数据库通信的语言。 第2章 检索数据 【关键字】作为SQL组成部分的保留字。关键字不能用作表或列的名字。 多条SQL语句必须以分号分隔。多数DBMS不需要在单条SQL语句后加分号。 第3章 排序检索数据 如果不明确规定排序顺序,则不应该假定检索出的数据的顺序有意义。 【子句】一个子句通常由一个关键字加上所提供的数据组成。 在指定一条order by子句时,应保证它是select语句中最后一条子句。该子句的次序不对将会出现错误信息。 通过非选择列进行排序。通常,order by子句中使用的列将是为显示所选择的列。但是,并不一定要这样,用非检索的列排序数据是完全合法的。 为了按多个列排序,简单指定列名,列名之间用逗号分开即可。 除了能用列名指出排序顺序外,order by还支持按相对列位置进行排序。 默认的排序顺序是升序排序asc。降序关键字是desc,它只应用到直接位于其前面的列名。如果想在多个列上进行降序排序,必须对每个列指定desc关键字。这个子句必须是select语句中的最后一条子句。 第4章 过滤数据 只检索所需数据需要指定搜索条件。在select语句中,数据根据where子句中指定的搜索条件进行过滤。where子句在表名from子句之后给出。它检查了一个列是否具有指定的值,据此进行过滤。 在同时使用order by和where子句时,应该让order by位于where之后,否则会产生错误。 where子句操作符: between,在指定的两个值之间;is null,为null值。<> 不等于。 单引号用来限定字符串,如果將值和串类型的列进行比较,则需要限定引号,用来与数值列进行比较的值不用引号。 在使用between时,必须指定两个值——所需范围的低端和高端值。这两个值必须用and关键字分隔。 NULL,它与字段包含0、空字符串或仅仅包含空格不同。 第5章 高级数据过滤 为了通过不止一个列进行过滤,可使用and操作符给where子句附加条件。 or操作符,指示数据库管理系统软件检索匹配任一条件的行,事实上,许多DBMS在or where子句的第一个条件满足的情况下,不再计算第二个条件。 SQL在处理or操作符前,优先处理and操作符。任何时候使用具有and和or操作符的where子句,都应该使用圆括号明确的分组操作符。 in操作符用来指定条件范围,范围中的每个条件都可以进行匹配。in取合法值的由逗号分隔的清单,全都括在圆括号中。 where子句中的not操作符有且只有一个功能,那就是否定它之后所跟的任何条件。not可以用在要过滤的列前,而不仅是在其后。 第6章 用通配符进行过滤 【通配符】用来匹配值的一部分的特殊字符。 【搜索模式】由字面值、通配符或两者组合构成的搜索条件。它只能用于文本字段,非文本数据类型字段不能使用通配符搜索。 %表示任何字符出现任意次数。 _只匹配单个字符而不是多个字符。 [ ]通配符用来指定一个字符集,它必须匹配指定位置的一个字符。此通配符可以用钱追符号^来否定。 通配符搜索的处理一般要比前面讨论的其他搜索所花时间长。 使用技巧:不要过分使用通配符。除非绝对有必要,否则不要把他们用在搜索模式的开始处。仔细注意通配符的位置。 第7章 创建计算字段 存储在数据库表中的数据一般不是应用程序所需要的格式。我们需要直接从数据库中检索出转换、计算或格式化过的数据,而不是检索出数据,然后再在客户机应用程序中重新格式化。 计算字段并不实际存在于数据库表中。计算字段是运行时在select语句内创建的。 只有数据库知道select语句中的哪些列是实际的表列,哪些列是计算字段。从客户机的角度来看,计算字段的数据是以其他列的数据相同的方式返回的。 【拼接】將值联结到一起构成一个值。 在SQL的select语句中,可使用一个特殊的操作符来拼接两个列。此操作符可用+或||表示。||为首选语法。 MYSQL中的拼接,使用concat()函数把项表拼接起来。 RTRIM() 函数去掉值右边的所有空格,通过这个函数,各个列都进行了整理。 LTRIM(),去掉串左边的空格。 TRIM(),去掉串左右两边的额空格。 列别名是一个字段或值的替换名。别名用as关键字赋予。 第8章 使用数据处理函数 SQL函数是不可移植的。 大多数SQL实现支持以下类型的函数: 用于处理文本串(如删除或填充值,转换值为大写或小写)的文本函数。 用于在数值数据上进行算术操作(如返回绝对值,进行代数运算)的数值函数。 用于处理日期和时间值并从这些值中提取特定成份的日期和时间函数。 返回DBMS正使用的特殊信息的系统函数。 SOUNDEX是一个將任何文本串转换为描述其语言表示的字母数字模式的算法。 第9章 汇总数据 使用聚集函数,SQL查询可用于检索数据,以便分析和报表生成。比如:确定表中行数,获得表中行组的和,找出表列的最大、最小和平均值。 【聚集函数】运行在行组上,计算和返回单个值的函数。 AVG()可用来返回所有列的平均值,也可以用来返回特定列或行的平均值。它只能用来确定特定数值列的平均值,而且列名必须作为函数参数给出。为了获得多个列的平均值,必须使用多个AVG()函数。 COUNT()函数进行计数。可利用它来确定表中行的数目或符合特定条件的行的数目。 COUNT()函数有两种使用方式: 使用COUNT(*)对表中行的数目进行计数,不管表列中包含的是空值还是非空值。 使用COUNT(column)对特定列中具有值的行进行计数,忽略null值。 MAX()返回指定列中的最大值。MAX()要求指定列名。在用于文本数据时,如果数据按相应的列排序,则MAX()返回最后一行。它忽略列值为NULL的行。 MIN()返回指定列的最小值。 SUM()用来返回指定列值的和。它忽略值为null的行。 利用标准的算术操作符,所有聚集函数都可用来执行多个列上的计算。 对以上5个聚集函数都可以如下使用: 对所有的行执行计算,指定ALL参数或不给参数; 只包含不同的值,指定DISTINCT参数。 如果指定列名,则DISTINCT只能用于COUNT()。DISTINCT不能用于COUNT(*)。类似的,DISTINCT必须使用列名,不能用于计算或表达式。 第10章 分组数据 GROUP BY子句指示DBMS分组数据,然后对每个组而不是每个结果进行聚集。 如果在GROUP BY子句中嵌套了分组,数据将在最后规定的分组上进行汇总。在建立分组时,指定的所有列都一起计算,所以不能从个别的列取回数据。 GROUP BY子句中列出的每个列都必须是检索列或有效的表达式(但不能是聚集函数)。如果在select中使用表达式,则必须在group by子句中指定相同的表达式,不能使用别名。 大多数SQL实现不允许GROUP BY列带有长度可变的数据类型。 除聚集计算语句外,select语句中的每个列都必须在GROUP BY子句中给出。 如果分组列中具有NULL值,则NULL將作为一个分组返回。如果列中有多行NULL值,它们將分为一组。 GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前。 除了能用GROUP BY分组数据外,SQL还允许过滤分组,规定包括哪些分组,排除哪些分组。所有类型的WHERE子句都可以用HAVING来替代。唯一的差别是WHERE过滤行,而HAVING过滤分组。 WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。WHERE排除的行不包括在分组中,这可能改变计算值,从而影响HAVING子句中基于这些值过滤掉的分组。 应该仅在与GROUP BY子句结合时才使用HAVING,而WHERE子句用于标准的行级过滤。 一般在使用GROUP BY子句时,应该也给出ORDER BY子句。这是保证数据正确排序的唯一方法。 第11章 使用子查询 在SELECT语句中,子查询总是从内向外处理。作为子查询的SELECT语句只能查询单个列,企图检索多个列將返回错误。 完全限定列名:表名和列名由一个句点分隔。 第12章 联结表 关系表的设计就是要保证把信息分解成多个表,一类数据一个表。个表通过某些常用的值互相关联。 表中唯一的标识,称为主键。 联结不是物理实体,它在实际的数据库表中不存在。联结由DBMS根据需要建立,它存在于查询的执行当中。 在引用的列可能出现二义性时,必须使用完全限定列名。 由没有联结条件的表关系返回的结果为笛卡儿积。检索出的行的数目将是第一个表中的行数乘以第二个表中的行数。 等值联结,它是基于两个表之间的相等测试。这种联结也称为内部联结。A INNER JOIN B ON A.id = B.id; 不要联结不必要的表,联结的表越多,性能下降的越厉害。 第13章 创建高级联结 别名除了用于列名和计算字段外,SQL还允许给表名起别名,这样做可以缩短SQL语句,允许单条SELECT语句中多次使用相同的表。 表别名不仅能用于WHERE子句,还可以用于SELECT的列表、ORDER BY 子句以及语句的其他部分。 表别名只在查询执行中使用。与列别名不一样,表别名不返回到客户机。 使用表别名的主要原因之一是能在单条SELECT语句中不止一次引用相同的表。 自联结通常作为外部语句用来替代从相同表中检索数据的使用子查询语句。 无论何时对表进行联结,应该至少有一个列出现在不止一个表中。标准的联结返回所有数据,甚至相同的列出现多次。自然联结排除多次出现,使每个列只返回一次。 自然联结就是这样一种联结,其中你只能选择哪些唯一的列,这一般是通过对表使用通配符SELECT * ,对所有其他表的列使用明确的子集来完成。 外部联结:包含那些在相关表中没有关联行的行。 在使用OUTER JOIN语法时,必须使用RIGHT或LEFT关键字指定包括其所有行的表(RIGHT指的是OUTER JOIN右边的表,而LEFT指出的是OUTER JOIN左边的表)。 *=操作符用来指定包括左边表中的每一行。它为左外部联结操作符,从左边表中检索所有行。而右外部联结操作符用=*表示。 左外部联结和右外部联结直接唯一差别时所关联的表的顺序。左外部联结可通过颠倒FROM或WHERE子句中表的顺序转换为右外部联结。 全外部联结FULL OUTER JOIN,检索两个表中所有行并关联那些可以关联的行。包含来自两个表的不关联的行。 第14章 组合查询 有两种情况,其中需要使用组合查询: 在单个查询中从不同的表类似返回结构数据; 对单个表执行多个查询,按单个查询返回数据。 多数情况下,组合相同表的两个查询完成的工作与具有多个WHERE子句条件的单条查询完成的工作相同。 UNION的使用:给出每条SELECT语句,在各条语句之间放上关键字UNION。 UNION必须由两条或两条以上的SELECT语句组成,语句之间用关键字UNION分隔。 UNION中的每个查询必须包含相同的列、表达式或聚集函数,不过各个列不需要以相同的次序列出。 列数据类型必须兼容:类型不必完全相同,但必须是DBMS可以隐含的转换类型。 UNION从查询结果集中自动去除了重复的行。如果想返回所有匹配行,可以使用UNION ALL而不是UNION。 在用UNION组合查询时,只能使用一条ORDER BY子句,它必须出现在最后一条SELECT语句之后。对于结果集,不存在用一种方式排序一部分,而又用另一种方式排序另一部分的情况,因此不允许使用多条ORDER BY子句。 虽然ORDER BY子句似乎只是最后一条SELECT语句的组成部分,但实际上DBMS將用它来排序所有SELECT语句返回的所有结果。 第15章 插入数据 INSERT是用来插入或添加行到数据库表的。插入可以用几种方式使用: 插入完整的行; 插入行的一部分; 插入某些查询的结果。 INSERT INTO A(a, b, c) VALUES ('1', '2', '3'); 如果某个列没有值,应该使用NULL值。 如果表的定义允许,则可以在INSERT操作中省略某些列。省略的列必须满足以下某个条件: 该列定义为允许NULL值; 在表定义中给出默认值。 INSERT SELECT可以將一条SELECT语句的结果插入表中。两个表中不应该重复使用相同的主键值。其中的SELECT语句可包含WHERE子句以过滤插入的数据。 不一定要求列名匹配。事实上,DBMS甚至不关心SELECT返回的列名,它使用的是列的位置。 INSERT通常只插入一行,为了插入多行,必须执行多个INSERT语句。 为了将一个表的内容复制到一个全新的表,可使用SELECT INTO语句。它与INSERT SELECT增补数据到一个已经存在的表不同,SELECT INTO將复制数据到一个新表。INSERT SELECT导出数据,SELECT INTO导入表。 SELECT INTO要想只复制列的子集,可明确地给出列名而不是使用*通配符。 SELECT INTO注意: 任何SELECT选项和子句都可以使用,包括WHERE和GROUP BY; 可利用联结从多个表插入数据; 不管从多少个表中检索数据,数据都只能插入到单个表中。 第16章 更新和删除数据 UPDATE:更新表中特定行;更新表中所有行。 UPDATE组成:要更新的表;列名和它们的新值;确定要更新哪些行的过滤条件。 UPDATE A SET a='1' WHERE b='2'; 在更新多个列时,只需要使用单个SET命令。 UPDATE语句中可以使用子查询,使得能用SELECT语句检索出的数据更新列数据。 为了删除某个列的值,可以设置它为NULL(假如表定义允许NULL值)。 DELETE:从表中删除特定的行;从表中删除所有行。 DELETE FROM A WHERE a='1'; DELETE不需要列名或通配符。DELETE删除整行而不是删除列。它不删除表本身。 从表中删除所有行:TRUNCATE TABLE 除非确实打算更新和删除每一行,否则绝对不要使用不带WHERE子句的UPDATE或DELETE语句。 保证每个表都有主键; 在对UPDATE或DELETE语句使用WHERE子句前,应该先用SELECT进行测试,保证它过滤的是正确的记录。 使用强制实施引用完整性的数据库,这样DBMS將不允许删除具有与其他表相关联的数据的行。 第17章 创建和操纵表 创建表的方法: 多数DBMS都具有交互式创建和管理表的工具; 表也可以用SQL语句操纵。 CREATE TABLE创建表,必须给出下列信息: 新表的名字,在关键字CREATE TABLE之后给出; 表列的名字和定义,用逗号分隔; 有的DBMS还要求指定表的位置。 主键是其值唯一标识表中每一行的列。只有不允许NULL值的列可用于主键。 默认值用关键字DEFAULT指定,经常用于日期或时间戳列。 更新表定义:ALTER TABLE。 在表中包含数据时不要对其进行更新。 所有的DBMS都允许给现有的表增加列,不过对所增加列的数据类型有所限制。 许多DBMS不允许删除或更改表中的列。 多数DBMS允许重新命名表中的列。 许多DMBS对已经填有数据的列的更改有限制。 ALTER TABLE,必须给出下面信息: 在ALTER TABLE之后给出要更改的表名; 所做的更改的列表。 ALTER TABLE A ADD a char(10); 复杂的表结构更改一般需要手动删除过程: 用新的列布局创建一个新表; 使用INSERT SELECT从旧表复制数据到新表; 检验包含所需数据的新表; 重命名旧表; 用旧表原来的名字重命名新表; 根据需要,重新创建触发器、存储过程、索引和外键。 删除表:DROP TABLE A; 重命名表:RENAME 第18章 使用视图 视图是虚拟的表,与包含数据的表不同,视图只包含使用时动态检索数据的查询。 视图的一些常见应用: 重用SQL语句; 简化复杂的SQL操作; 使用表的组成部分而不是整个表; 保护数据; 更改数据格式和表示。 在视图创建之后,可以用与表基本相同的方式利用它们。可以对视图执行SELECT操作,过滤和排序数据,將视图联结到其他视图或表,甚至能添加和更新数据。 视图仅仅是用来查看存储在别处的数据的一种设施。视图本身不包含数据,因此它们返回的数据是从其他表中检索出來的。在添加或更改这些表的数据时,视图將返回改变过的数据。 关于视图创建和使用的一些规则和限制: 与表一样,视图必须唯一命名; 对于可以创建的视图数目没有限制; 为了创建视图,必须具有足够的访问权限; 视图可以嵌套; 许多DBMS禁止在视图查询中使用ORDER BY子句; 有的DBMS要求命名返回的所有列,如果列是计算字段,则需要使用别名; 视图不能索引,也不能有关联的触发器或默认值; 有的DBMS把视图作为只读的查询; 有的DBMS允许创建这样的视图,它不允许进行导致行不再属于视图的插入或更新。 CREATE VIEW只能创建不存在的视图。 用DROP删除视图。DROP VIEW A; 覆盖或更新视图,必须先DROP它,然后再重新创建它。 视图的另一个常见用途是重新格式化检索出的数据。它还可以过滤不想要的数据。 如果从视图检索数据时使用一条WHERE子句,则两组子句將自动组合。 视图对于简化计算字段的使用特别有用。 视图提供了一种封装SELECT语句的层次,可用来简化数据处理以及重新格式化基础数据或保护基础数据。 第19章 使用存储过程 存储过程,就是为以后的使用而保存的一条或多条SQL语句的集合。可将其视为批文件,虽然它们的作用不仅限于批文件。 存储过程的优点: 通过把处理封装在容易使用的单元中,简化复杂的操作; 由于不要求反复建立一系列处理步骤,保证了数据的一致性; 简化对变动的管理; 因为存储过程通常以编译过的形式存储,所以DBMS为处理命令所做的工作较少。结果是提高了性能; 执行存储过程的SQL语句即EXECUTE,接受存储过程名和需要传递给它的任何参数。 创建存储过程:CREATE PROCEDURE 第20章 管理事物处理 事务处理可以用来维护数据库的完整性,它保证成批的SQL操作要么完全执行,要么完全不执行。 事务处理是一种机制,用来管理必须成批执行的SQL操作,以保证数据库不包含不完整的操作结果。利用事务处理,可以保证一组操作不会中途停止,它们或者作为整体执行,或者完全不执行。如果错误发生,整组语句提交给数据库表。如果发生错误,则进行回退以恢复数据库到某个已知且安全的状态。 【事务】一组SQL语句; 【回退】撤销指定SQL语句的过程; 【提交】將未存储的SQL语句结果写入数据库表; 【保留点】事务处理中设置的临时占位符,可以对它们发布回退。 事务处理用来管理INSERT、UPDATE和DELETE语句,不能回退SELECT语句,也不能回退CREATE或DROP操作。 管理事务处理的关键在于將SQL语句组分解为逻辑块,并明确规定数据何时应该回退,何时不应该回退。 SQL的ROLLBACK命令用来回退SQL语句。 一般的SQL语句都是直接针对数据库执行和编写的。这就是所谓的隐含提交,即提交操作是自动运行的。但是,在事务处理块中,提交不会隐含的进行。为进行明确的提交,使用COMMIT语句。 为了支持回退部分事务处理,必须能在事务处理块中合适的位置放置占位符。在SQL中,这些占位符称为保留点。创建占位符,使用SAVEPOINT语句。 可以在SQL代码中设置任意多的保留点,越多越好。 第21章 使用游标 【结果集】SQL查询所检索出的结果。 【游标】是一个存储在DBMS服务器上的数据库查询,它不是一条SELECT语句,而是被该语句检索出來的结果集。在存储了游标之后,应用程序可以根据需要滚动或浏览其中的数据。 游标的一些选项和特性: 能够标记游标为只读,使数据能读取,但不能更新和删除; 能控制可以执行的定向操作; 能标记某些列为可编辑的,某些列为不可编辑的; 规定范围,使游标对创建它的特定请求或对所有请求可以访问; 指示DBMS对检索出的数据做复制,使在游标打开和访问期间数据不变化。 游标主要用于交互式应用,其中用户需要滚动屏幕上的数据,并对数据进行浏览或做出更改。 使用游标的步骤: 在能够使用游标前,必须声明它。这个过程实际上没有检索数据,它只是定义要使用的SELECT语句和游标选项。 一旦声明后,必须打开游标以供使用。这个过程用前面定义的SELECT语句把数据实际检索出来。 对于填有数据的游标,根据需要检索各行。 在结束游标使用时,必须关闭游标,而且可能的话,释放游标。 在声明游标后,可根据需要频繁的打开和关闭游标。在游标打开时,可根据需要频繁的执行取操作。 创建游标:DECLARE CURSOR命名游标,并定义相应的SELECT语句,根据需要带WHERE和其他子句。 使用游标:OPEN CURSOR语句打开。 访问游标数据:FETCH指出要检索的行,从何处检索它们以及將它们放于何处。 关闭游标:CLOSE语句。 第22章 了解高级SQL特性 关系数据库存储分解为多个表的数据,每个表存储相应的数据。利用键来建立从一个表到另一个表的引用。 【约束】管理如何插入或处理数据库数据的规则。 大多数约束是在表定义中定义的。 【主键】PRIMARY KEY是一种特殊的约束,它用来保证一个列或一组列中的值时唯一的,并且永不改动。表中的一个列的值唯一标识表中的行。 主键的满足条件: 任意两行的主键值都不相同; 每行都具有一个主键值(不允许空值); 包含主键值的列不修改或更新; 主键值不能重用。如果从表中删除某一行,其主键值不分配给新行。 【外键】REFERENCES的值必须在另一表的主键中列出。外键是保证引用完整性的一个极重要的成份。 外键可帮助防止意外的删除。 【唯一约束】UNIQUE保证一个列中的数据唯一。 唯一约束与主键的区别: 表可包含多个唯一约束;唯一约束列可包含NULL值;唯一约束列可修改或更新;唯一约束列的值可重复使用;唯一约束不能用来定义外键。 【检查约束】CHECK用来保证一个列中的数据满足一组指定的条件。 检查约束的常见用途为: 检查最小或最大值。指定范围。只允许特定的值。 数据类型限制了列中可保存的数据的类型。检查约束在数据类型内又做了进一步的限制。 【索引】CREATE INDEX用来排序数据以加快搜索和排序操作的速度。 主键数据总是排序的,因此,按主键检索特定行总是一种快速有效的操作。 可以在一个或多个列上定义索引,使DBMS保存其内容的一个拍过序的列表。在定义了索引后,DBMS搜索排过序的索引,找出匹配的位置,然后检索出这些行。 索引改善检索操作的性能,但降低数据插入、修改和删除的性能。 索引数据可能要占用大量的存储空间。 并非所有数据都适合于索引。 索引用于数据过滤和数据排序。 可以在索引中定义多个列。 索引必须唯一命名。 【触发器】TRIGGER是特殊的存储过程,它在特定的数据库活动发生时自动执行。可以与特定表上的INSERT、UPDATE和DELETE操作相关联。 触发器与单个表相关联。 触发器内的代码具有以下数据的访问权: INSERT操作中的所有新数据; UPDATE操作中的所有新数据和旧数据; DELETE操作中删除的数据。 触发器的常见用途: 保证数据一致; 基于某个表的变动在其他表上执行活动; 进行额外的验证并根据需要回退数据; 计算计算列的值或更新时间戳。 一般来说,约束的处理比触发器快,因此在可能的时候,应该尽量使用约束。 需要保护的操作有: 对数据库管理功能的访问; 对特定数据库或表的访问; 访问的类型; 仅通过视图或存储过程对表进行访问; 创建多层次的安全措施,从而允许多种基于登录的访问和控制; 限制管理用户账号的能力。 安全性通过SQL的GRANT和REVOKE语句来管理。 ODBC是一个标准,它使客户机应用能与不同的后端数据库或基础数据库引擎交互。使用ODBC,能够在一个客户机中编写代码,并使前述各种工具与几乎所有数据库或DBMS交互。 ODBC客户机应用程序并不直接与数据库交互,而是与ODBC数据源交互。数据源是一个逻辑数据库,它包括驱动程序和如何连接到数据库的信息(文件路径、服务器名等)。 在定义了ODBC数据源后,任何兼容ODBC的应用程序都可以使用这些数据源。ODBC数据源并不针对具体的应用程序,针对的是系统。 引自 全书笔记
346人阅读
说明 · · · · · ·
表示其中内容是对原文的摘抄