SQL数据库标准语言, since 2021-12-11

(2021.12.11 Sat)
关系型数据库中,一个表格称为关系,每一行称为一个记录,每个列是一个属性。SQL中大小写不敏感(case-insensitive)。

定义语句

建立表语句

CREATE TABLE table_name (field_name1 type [NOT NULL [UNIQUE]], field_name2 type [NOT NULL [UNIQUE]], ...);

说明:

  1. SQL列的数据类型包括
    • CHAR(n): 长度为n的字符串型
    • DECIMAL[(m[, n])]: 共m位(不包含小数点)且有n位小数的数。当mn省略时,其含义由系统自定义。该类型为精确数值类型,还可写成DEC(m[, n])或NUMERIC(m[, n])
    • INTEGER或INT: 四字节或二字节整数
    • SMALLINT: 二字节整数
    • FLOAT(n): n位有效数字的实型数
    • REAL: 单精度实型数
    • DOUBLE PRECISION: 双精度实型数
CREATE TABEL student (sid CHAR(2) NOT NULL UNIQUE, name CHAR(10), age SMALLINT, gender CHAR(2));

从其他表复制创建

CREATE TABLE table2 LIKE table1;
INSERT INTO table2 SELECT * FROM table1;

扩充表(添加列)

ALTER TABLE <table_name> ADD (field_name1 type [NOT NULL], field_name2 ...);

ALTER TABLE sudent ADD (birthplace CHAR(10)); //添加列birthplace
ALTER TABLE stu_score_bk ADD (sid INT AUTO_INCREMENT, PRIMARY KEY (sid)); 
// 添加一列sid,并将其设置为自加和primary key

修改表

ALTER TABLE <table_name> MODIFY (field_name1 type [NOT NULL], field_name2 type ...);

该语句可以修改表中列的类型和长度,但不能修改列名本身。若一个列要修改数据类型,则该数据必须全为空值。

删表

DROP TABLE <table_name>;

增删改UPDATE/DELETE/INSERT

增删改操作是对数据的基本操作,属于数据操作语言(Data Manipulation Language)。不同于前面的创建、添加、删表等操作,这些被成为数据定义语言(Data Definition Language),其实现了对数据库结构和操作的定义。DDL指令在执行之后会隐式执行commit操作,即对数据库做了对应的动作。而DML语言并不隐式含有commit操作,需要手动执行commit指令才能实现对数据的修改。在执行DML操作后,手动加入commit指令。

START TRANSACTION;
...
INSERT INTO Student (name,department) values ("xiaoming","computer science");
COMMIT;

删除记录

DELETE FROM student_table where name = 'xiaoming';

此外,执行操作后是否需要commit也需要考虑数据引擎。对于不支持事务的引擎,如myisamcommit指令无效。而支持事务的引擎,如innodb,支持自动提交commit

查看数据库是否支持commit,可用如下指令查看,如果返回结果为on,则支持查看。

mysql > show variables like '%autocommit%';

约束

(2021.12.15 Wed)

  • DEFAULT: 用于向列中插入默认值。如果没有其他的规定,默认值会被添加到所有新记录。在创建表和修改表时都可以使用。
CREATE TABLE some_table
(
PID INT NOT NULL,
...
city VARCHAR(255) DEFAULT 'HONGKONG',
OrderDate DATE DEFAULT GETDATE()
)
ALTER TABLE some_table
ALTER city SET DEFAULT 'London';

撤销DEFAULT约束

ALTER TABLE some_table
ALTER city DROP DEFAULT

CHECK约束
用于限制列中的值的范围。如果对单个列定义 CHECK 约束,那么该列只允许特定的值。如果对一个表定义 CHECK 约束,那么此约束会在特定的列中对值进行限制。

CREATE TABLE Persons
(
Id_P int NOT NULL,
...
City varchar(255),
CHECK (Id_P>0)
)

如果命名 CHECK 约束,以及为多个列定义 CHECK 约束,采用如下方法

CREATE TABLE Persons
(
Id_P int NOT NULL,
City varchar(255),
CONSTRAINT chk_Person CHECK (Id_P>0 AND City='Sandnes')
)

在修改表的过程中

ALTER TABLE Persons
ADD CHECK (Id_P>0)

如果命名 CHECK 约束,以及为多个列定义 CHECK 约束,采用如下方法

ALTER TABLE Persons
ADD CONSTRAINT chk_Person CHECK (Id_P>0 AND City='Sandnes')

撤销约束

ALTER TABLE Persons
DROP CHECK chk_Person

自增auto_increment
每次插入新纪录时,自动的创建主键字段的值。
下面这个例子中,创建表Persons,设置字段PId为自增字段,将其设置为主键。

CREATE TABLE Persons
(
PId int NOT NULL AUTO_INCREMENT,
...
City varchar(255),
PRIMARY KEY (PId)
)

默认的auto_increment字段的初值为1,每条新记录自增加1.
要让auto_increment字段的初始值从其他值开始,需要使用如下指令

ALTER TABLE Persons AUTO_INCREMENT=99;

向这个表中添加数据时,不需要指定PId的值,自动加1.

INSERT INTO Persons (FirstName,LastName)
VALUES ('Bill','Gates')

其他SQL服务器的命令和MySQL不同。

SQL简单查询 select...from...where

(2021.12.12 Sun)
基本格式如下

SELECT * FROM table_name

该格式选择表中所有属性返回。对表属性做投影,可直接写出所选属性

SELECT field_name1, field_name2, ... FROM table_name

选择的属性可以重命名,用AS关键字,或不用关键字,只用空格隔离;选择的属性可以重新赋值;可重新定义属性的值

SELECT field_name1 AS field_name_edited,
field_name2 field_name_edited_2,
field_name3 * 0.5 field_name_edited_3,
'hrb' AS field_name_new
FROM table_name

关系运算符
除了常见的加减乘除等,还有对字符的连接操作||,如'foo' || 'bar'的运算结果是'foobar'。对字符串的比较操作,实际上是比较字符串在字典中的顺序(假想字符串出现在字典中)。哪个字符串在前,哪个字符串的值比较小。比如'fodder' < 'foo''bar'<'bargin'

另外,需要注意的是,尽管SQL语言本身大小写不敏感,但是涉及字符串的操作,或对字符串的操作,是大小写敏感的。

模式匹配

s LIKE p

其中的p表示模式,该指令用于匹配(字符串)属性s与模式p。模式中的%表示匹配任意多个(含0)字符,_表示任意一个字符。

SELECT title FROM movies
WHERE title LIKE 'Star _ _ _ _';

该指令返回的可能结果是Star TrekStar Wars

符号%可匹配0或任意多个字符。

SELECT title
FROM Movies 
WHERE title LIKE '% ' ' s%';

SQL约定,字符串中两个连续的单引号表示一个单引号,而不作为字符串的结束符。该代码表示是查询名字中含有's的所有电影。

日期和时间
日期由DATE关键字加上表示日期的特定形式字符串组成

DATE'YYYY-MM-DD'

DATE'1960-01-01'

时间和时间戳类似于日期,其关键字分别是TIMETIMESTAMP

TIME'15:00:00.5'
TIMESTAMP'2021-12-12 09:46:35'

空值和涉及空值的比较
空值NULL有几种常见的解释

  • value unknown未知值,知道其有值但不知道其值
  • value inapplicable不适用的值,任何值在这里都没有意义,如MovieStar关系中,如果该演员单身,则spouse属性为空,因为没配偶
  • value withheld保留的值,属于某对象但无权知道的值,比如未公布的电话号码属于空值

空值运算的规则

  1. NULL与任何值(包括一个空值)进行算术运算,如加减乘除,其结果仍然是空值NULL
  2. 对空值做比较运算,包括与另一个NULL值做比较,结果都是UNKNOWN,而UNKNOWN值时另外一个与TRUEFALSE相同的布尔值

注意,NULL可出现在元组中,但它不是一个常量,因此可对空值表达式进行运算,但不可以直接将NULL作为一个操作数。

正确判断x的值时否为NULL的方式

x IS NULL

关于UNKNOWN有下面关系

NOT UNKNOWN --> UNKNOWN
TRUE AND UNKNOWN --> UNKNOWN
FALSE AND UNKNOWN --> FALSE
TRUE OR UNKNOWN --> TRUE
FALSE OR UNKNOWN --> UNKNOWN

排序ORDER
排序指令ORDER BY对输出结果进行排序,默认是升序ASC,也可进行降序DESC排列。除了对某个属性的值按升序或降序排列,也可以对多个属性值的运算做排序。

SELECT * 
FROM Movies
WHERE studioName = 'Disney' AND year = 1990
ORDER BY A+B DESC;

多关系查询

SQL用简单的方式在一个查询中处理多个关系:在FROM子句中列出每个关系,用逗号隔开,在SELECT子句和WHERE子句中引用任何出现在FROM子句中关系的属性。

为避免引用属性歧义,可以在FROM子句中给关系赋缩略名,或者在调用关系中的属性时直接加入关系的名字。

SELECT a.name, b.length
FROM Movies a, MovieExec b
WHERE a.name = b.name;

子查询subquery

在SQL中,一个查询可以通过不同的方式被用来计算另一个查询,当某个查询是另一个查询的一部分是,称之为子查询subquery。

子查询可以返回单个常量,这个常量能再WHERE子句中和另一个常量做比较。子查询能返回关系,该关系可以在WHERE子句中以不同的方式使用。子查询形成的关系也能出现在FROM子句中,并且后面紧跟该关系的元组变量。

SELECT name
FROM MovieExec
WHERE cert IN
           (SELECT producerC
            FROM Movies
            WHERE (title, yer) IN
                      (SELECT movieTitle, movieYear
                       FROM StarsIn
                       WHERE starName = 'Harrison Ford'
                      )
           );

该查询返回Harrison Ford演过的电影的制片人。

SELECT name
FROM MovieExec, (SELECT producerC,
                                 FROM Movies, StarsIn
                                 WHERE title = movieTitle AND 
                                       year = movieYear AND
                                       starName = 'Harrison Ford'
                                 ) Prod
WHERE cert  = Prod.producerC;

使用FROM子句子查询找出Ford出演的电影的制片人。

子查询也可产生标量。

SELECT name
FROM MovieExec
WHERE cert = 
           (SELECT producerC
            FROM Movies
            WHERE title = 'Star Wars'
           );

此外,也可使用LEFT/RIGHT/INNER/OUTER JOIN的命令实现关系的连接。(略)

与子查询经常一同出现的谓词包括IN, ALL, ANY, EXISTS

SELECT snum, sscore
FROM SCORE
WHERE course_num = 'c2' AND sscore > ALL
                                        (SELECT sscore
                                         FROM SCORE
                                         WHERE course_num = 'c5');

该查询返回c2成绩高于c5最高成绩的学生号和成绩。如果其中的关键词换成ANY,则返回c2成绩高于c5最低成绩的学生号和成绩。

函数查询和聚集

常见的函数查询包括

  • AVG(field_name): 求指定数值列秩的算数平均值
  • COUNT(field_name): 求指定列中,值的个数
  • MAX(field_name)/MIN: 值的最大或最小值
  • SUM(field_name): 值的总和

注意,COUNT(*)用于查询有多少条记录,其前不能使用DISTINCT关键字。而如果求某属性有多少个不重合的值,需使用COUNT(DISTINCT field_name)如果只是使用指令COUNT(field_name),则返回A属性非空的元组个数之和。AVG(field_name+5)表示对field_name属性的值都加5再求均值。在使用SUM(field_name)时,如果field_name属性中含有NULL值,则返回的和应为NULL

GROUP分组和HAVING条件
分组操作往往与函数查询联合使用。

SELECT A, COUNT(B)
FROM R
GROUP BY A;

HAVING子句有这两个规则

  • HAVING子句中的聚集只应用到正在检测的分组上
  • 所有FROM子句中关系的属性都可以在HAVING子句中用聚集运算,但是只有出现在GROUP BY子句中的属性,才可能以不聚集的方式出现在HAVING子句中。

(2022.07.22 Fri)
GROUP BY命令有另外两个OLAP修饰符联合使用,ROLLUPCUBE。这两个修饰符的作用如下

  • ROLLUP:对分组后各组的聚合结果进行汇总,在结果中输出,提供更高一级的聚合操作。即如果聚合函数是AVG,则加了WITH ROLLUP提示符后,额外输出一行,记录所有分组的AVG。这个操作相当于做分组操作的结果与对全体数据做相同操作的结果的UNION ALL。比如求一个班级里面各科目的平均分,并在此基础上计算所有科目的平均分
SELECT AVG(score) as avgscore, subject FROM score_table
GROUP BY subject WITH ROLLUP;
// or
SELECT AVG(score) AS avgscore, subject FROM score_table
GROUP BY subject 
UNION ALL
SELECT 'total', AVG(score) AS avgscore FROM score_table
  • CUBE:生成的结果集显示了所选列中值的所有组合的聚合,而ROLLUP生成的结果集显示了所选列中值的某一层次结构的聚合。CUBE案例:在MySQL 8.0上暂时运行失败,placeholder。

其他函数

(2021.12.15 Wed)

  • FIRST/LAST(field_name): 返回该列的第一个/最后一个元素,该命令仅适用于MS Access。
SELECT FIRST(field_name) FROM table;
SELECT LAST(field_name) FROM table;

在MySQL中,返回该列的第一个/最后一个元素用如下方式

SELECT field_name
FROM table
ORDER BY field_name ASC/DESC (?)
LIMIT 1;

(2022.07.31 Sun)
注意这里的LIMIT是一个分页函数,常规的用法是

LIMIT <starting_line>, <row_counter>;

该指令用于读取特定行(starting_line)开始的row_counter行数据。如果不指定开始行如LIMIT 20,则从0行开始读取row_counter行数据,即前20行数据。

分页函数的另一种语法是

LIMIT <row_counter> OFFSET <starting_line>;

  • UCASE/LCASE(field_name): 把所选字段的值都改为大写/小写。在SQL server中是UPPER/LOWER。
SELECT UCASE(city_name) AS city_name_upper FROM city_table;
  • MID(field_name, start[, length])/SUBSTR(field_name, start[, length]): 从文本字段中提取字符。其中的start只能从1开始length表示提取的长度,不标记则为返回剩余文本。MID和SUBSTR的动作完全相同。
SELECT MID(company_name, 1, 3) AS shorten_name FROM table;

如果table表中的这个字段第一个数据是Google,则返回Goo

  • LEN(field_name): 返回文本字段中值的长度。MySQL中该指令为LENGTH(field_name)
SELECT LENGTH(company_name) FROM table;

该字段中Google返回6.

  • ROUND(field_name[, digit]): 把数值字段舍入为指定位数的数字,默认的digit=0,即没有小数部分。返回值转换为BIGINT型。
SELECT ROUND(field_name, 0) FROM table;
  • NOW(): 返回系统当前时间,格式为YYYY-MM-YY HH:MM:SS
SELECT city_name, NOW() AS current_time FROM table;

返回Harbin, 2021-12-15 16:53:30

  • FORMAT(field_name, format): 对字段做格式转换。多用于时间格式转换。
SELECT FORMAT(NOW(), 'YYYY-MM-DD') AS nowtime, product_id FROM table;

一个用到局部变量的例子,在SQL server中,来自microsoft docs页面。

DECLARE @d DATE = GETDATE();  
SELECT 
FORMAT( @d, 'dd/MM/yyyy', 'en-US' ) AS 'Date',
FORMAT(123456789,'###-##-####') AS 'Custom Number';
  • CAST(field_name AS type_name(para)): 对字段类型做转换。注意CAST没有舍入截断操作,将小数转换为整数会产生错误。
SELECT CAST(number_field AS INT) AS number_field_int FROM table;
SELECT CAST(number_field AS decimal(9, 2)) AS decimal_field FROM table; # 表示最大位数9,2位小数,即9999999.00
SELECT CAST(some_id AS CHAR(4)) as id_char FROM table;

UNION操作符

(2021.12.16 Thur)
MySQL的UNION操作符用于将连接两个以上的SELECT语句的结果组合到一个语句中。可根据关键字ALL/DISTINCT来决定是选择全部结果还是删除重复结果。

SELECT field1, field2, field3 
FROM table1
UNION 
SELECT field1, field2, field3
FROM table2 

上面表达中,UNION表示默认情况,即删除重复结果,等效于UNION DISTINCT。如果想保留所有结果,含重复结果,使用UNION ALL指令。
(2022.07.15 Fri)
此外,UNION命令默认对结果排序,而UNION ALL不排序。从速度来看,显然UNION ALL更快。

视图view

视图是SQL中除了关系以外另一种基本数据结构。视图是数据库中满足一定约束条件的数据组成的表,但其本身不占用实际存储器。视图可看做是一个虚表。从用户角度看,关系和视图没有任何区别。

视图可用作某个用户的专用数据部分,便于使用,又提高了数据的独立性,也可以把表中数据隐藏起来,加强数据的保密性。

定义视图

CREATE VIEW <view_name> [(view_list)]
AS SELECT ...
[WITH CHECK OPTION];

结尾的WITH CHECK OPTION语句,如果省略,则视图是一个只读表,不限制插入到该视图的数据值;否则是一个可更新表,插入到该视图的数据值必须满足在该视图定义时SELECT语句指定的条件。
下面例子生成一个平均成绩视图。

CREATE VIEW ave_score (snum, name, gender, avg_s) 
          AS SELECT s.snum, s.name, s.gender, avg(sc.score)
          FROM student s, score sc
          WHERE s.snum = sc.snum
          GROUP BY snum;

视图的查询指令与关系相同。

视图的更新指令与基本表相同。但是一个视图要进行更新操作,应满足下面基本条件

  • 视图只由一个基本表导出
  • SELECT语句中不含有GROUP子句、组函数和DISTINCT
  • 视图中的列不是由表达式定义的
  • 基本表中全部带有NOT NULL的列都属于该视图

删除视图

DROP VIEW view_name

存储过程PROCEDURE

(2021.12.16 Thur)

SQL数据控制功能

控制功能指的是控制用户对数据的存储权力。
授权语句

GRANT grant_list ON table_name TO user_name/PUBLIC [WITH GRANT OPTION]

其中的grant_list是权力表,如果授予所有权利,则用ALL代替grant_list.
权力表包括

  • ALTER 修改表结构
  • SELECT 查询权
  • DELETE 删除记录
  • INSERT 插入新纪录权
  • UPDATE 对指定列或全体列的值修改的权利

ALL指代上面所有的权利。而如果所授予的不是数据表而是视图,则只能授予SELECT, DELETE, INSERT, UPDATE.

用户名可以是个别用户,也可以是全部用户,比如PUBLIC

如果出现WITH GRANT OPTION,则得到授权的用户可以向其他人授权。

取消授权

REVOKE ALL/grant_list ON table_name FROM user_name/public

SQL事务Transaction

目前,数据库上的操作模型是用户查询或更新数据库。数据库上的操作一次只执行一个,一个操作留下的数据正是下一个操作所要起作用的。操作中软硬件都不会出错,不会留下操作的结果不能解释的数据库状态。

可串行化

银行行业或机票预定中,往往出现多个人同时进行同一个业务,也就是同时修改数据库的情况。比如订机票,两个人同时看到有一个空位,并且(几乎)同时执行订票操作,到底谁顶到票呢?

为避免上面说的情况引起数据库系统的错误和崩溃,引入了串行化概念。SQL允许程序员规定一个特定的事务必须对于别的事物可以串行化(serializabel),即这些事物必须表现得好像他们是串行的(serially)执行,也就是一个时刻只有一个事物,相互之间没有重叠。

DBMS中一个普通的方式是锁定(lock)数据库的元素防止被两个函数同时访问。

前面订票的案例,如果两个用户对订票的操作是串行执行的,那么就不会出现前面提到的尴尬情况。

原子性atomic

考虑一个例子,从A账户到B账户转账100卢比。其中包含两个动作,一个是A账户减少100卢比,第二个是B账户增加100卢比。

在执行转账的过程,一旦硬件或网络出现问题,会无法完成这两个看似分开,但实则应为一体的动作。

该案例说明数据库的操作的某些组合需要原子地atomically执行,即他们要么都执行要么都不执行。一个简单的解决方案是将对数据库的所有修改都在一个本地工作区中执行,而且只有在所有工作都完成后才能修改提交(commit)到数据库,于是所有改变成为数据库的一部分,对其他操作可见。

事务Transaction

对可串行化和原子性问题的解决方案将把数据库操作分组为事务。事务是必须原子地执行一个或多个数据库操作的集合,即要么所有操作都执行要么所有操作都不执行。SQL要求默认事务以可串行化方式执行。

在SQL中,每条语句自身就是一个事务。不过SQL允许程序员将几条语句组成一个事务。用命令START TRANSACTION来标记事务的开始。有两种方式结束事务:

  1. SQL的COMMIT语句使得事务成功结束,即被提交了。在COMMIT被执行之前,改变是试探性的,对其他事务可不可见均有可能。
  2. SQL的ROLLBACK语句使得事务夭折abort或不成功结束。任何由该事务的SQL语句所引起的修改都被撤销,即被回滚rolled back。所以他们不会持久的出现在数据库中。

只读事务read-only

如果告知SQL执行系统当前的事务是只读事务,即它不会修改数据库,那么SQL系统很可能能够充分利用这一点。通常,多个访问同一个数据的只读事务可以并行执行,但是多个写同一个数据的事务并不能并行执行。
告知SQL系统下一个事务是只读事务的语句是

SET TRANSACTION READ ONLY;

这条语句必须在事务开始前执行。
可以通过如下语句通知SQL下一个事务可以写数据

SET TRANSATION READ WRITE;

不过这个选项是默认选项。

读脏数据dirty data(待补充)

脏数据表示还没有提交的事务所写的数据的通用术语。藏独dirty read是对脏数据的读取。读脏数据的风险是写数据的事务可能最终夭折。

有时可能需要冒险偶尔脏读一次,从而避免

  1. DBMS用啦防止脏读所作的耗时的工作
  2. 为了等到不可能出现脏读而造成的并发性的损失

使用SET TRANSACTION语句,SQL允许指定一个给定的事务是否可以脏读,比如

SET TRANSACTION READ WRITE
        ISOLATION LEVEL READ UNCOMMITED;

这个语句做了两件事,一是声明可以写数据,二是声明事务用读未提交read-uncommited的隔离层次进行。即允许事务读脏数据。

隔离层次

共四种,可串行化、读未提交(允许脏读)、读提交(read-commited)和可重复读(repeatable-read)。
他们可以通过如下语句指定

SET TRANSATION ISOLATION LEVEL READ COMMITED;
SET TRANSATION ISOLATION LEVEL REPEATABLE READ;

对每条语句,默认事务是读写的,所以在适当的情况下,可在每条语句后面加上READ ONLY。有一个指定选项

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

但这是SQL的默认情况,不必显式指定。

Reference

1 匙彦斌等主编,计算机软件技术基础教程,天津大学出版社
2 Jeffery U.等著,岳丽华等译,数据库系统基础教程,机械工业出版社

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容