Q语言——表

前言

表是Q中的第一类实体,这意味着它们是存储在内存中的数据结构,就像列表或字典一样。Q的表本质上是字典的一个集合。因此,与关系数据库中的面向行的表相比,Q表是面向列的。此外,由于列表(list)是有序的,因此表的列也是,而SQL的行顺序是未定义的。Q表包含有序列列表的事实使得kdb +在存储,检索和操作顺序数据方面非常有效。这就是时间序列数据。

Kdb +处理Q表的统一环境中处理关系和时间序列数据。没有单独的数据定义语言,没有单独的存储过程语言,也不需要将内部表示映射到单独的表单以进行持久化。

一、表的定义

1. 我们可以通过两种方式来定义Q的表。

    1. 使用字典转置的形式
q)dc:`name`iq!(`Dent`Beeblebrox`Prefect;98 42 126)  /定义一个字典
q)dc  /查看所定义字典的内容
name| Dent Beeblebrox Prefect
iq  | 98 42  126
q)dc[`iq;]  /字典的查询
98 42 126
q)dc[;2]  /字典的查询
name| `Prefect
iq  | 126
q)dc[`iq; 2]  /字典的查询
126
q)t:flip `name`iq!(`Dent`Beeblebrox`Prefect;98 42 126) /通过将字典flip的形式来创建一个表
q)t  /查看创建表的内容,通过对比,我们看出字典与表的输出展现形式的不同,字典是用竖线分隔key和value,表示用横线分隔column name和value
name  iq
--------------
Dent  98
Beeblebrox 42
Prefect  126
q)dc  /查看字典的内容
name| Dent Beeblebrox Prefect
iq  | 98 42  126
q)t[;`iq]  /标的value值查询方式,正好与字典的相反
98 42 126
q)t[2;]
name| `Prefect
iq  | 126
q)t[2;`iq]
126
q)type dc  /查询字典的类型值,字典为99h
99h
q)type t  /查询表的类型值,字典为98h
98h

t[integer;symbol name]:

· 它是一个二维数据结构,索引时第一个参数为整数索引值,第二个参数为符号列名。如:

q)t[2;`iq]
126

· 若只给第一个参数,即[integer],则检索表中的第integer行的数据,返回的结果为字典的形式。如:

q)t[2]
name| `Prefect
iq  | 126

· 若只给第二个参数,即[;symbol name],则检索表中的symbol name列的数据,返回结果为列表。如:

q)t[;`iq]
98 42 126

· 若给定两个参数,t[integer;symbol name],则检索integer行,symbol name列的具体数据。如:

q)t[2;`iq]
126 

· 表在逻辑上是字典中的列表。

· 转置字典的唯一效果是颠倒其索引的顺序; 没有改变数据结构。

    1. 使用标准定义语法
table:([] c 1:L 1 ; ...; c n:L n),通过这种方法定义表更加具有可读性。这里这里c i是表示列名的符号,L i是列值的对应列表。
q)t:([] name:`Dent`Beeblebrox`Prefect; iq:98 42 126) /利用标准形式定义表
q)t
name  iq
--------------
Dent  98
Beeblebrox 42
Prefect  126
q)t~flip `name`iq!(`Dent`Beeblebrox`Prefect;98 42 126) /可以看出两种方式创建的表类型是一样的
1b

2. 表的元数据

我们可以通过meta关键字来查看标的数据信息(元数据)。

q)t:([] name:`Dent`Beeblebrox`Prefect; iq:98 42 126) /创建一个表t
q)t  /显示表t的内容
name  iq
--------------
Dent  98
Beeblebrox 42
Prefect  126
q)meta t  /通过meta关键字来查看表t的结构信息。
c  | t f a
----| -----
name| s
iq  | j

meta返回的结果当中,具有如下信息:

· 结果c包含表的列名称;

· 该列t包含一个type char的结果类型,表示该列的数据类型,如name列数据类型为s(symbol类型);

· 该列f包含任何外键或链接列;

· 该列a包含与所在列的所有属性(如排序(sorted)、去重(unique))。

我们也可以通过tables关键字来显示当前有哪些表在内存中。

q)tables `.  /通过tables+`.操作可以查看当前内存中有哪些表存在
,`t
q)t2:([] c1:1 2 3; c2:(1 2; enlist 3; 4 5 6))
q)tables `.
`s#`t`t2
q)t1:([] c1:1 2 3 4 5;c2:`a`b`c`d`e)
q)tables `.
`t`t1`t2

二、空表

与其他数据库一样,很多时候我们一开始建立的表格都是一个空表,建立空表我们可以指定字段(列)的数据格式,也可以不指定,不指定的情况下由第一次给表添加数据的格式来决定。

q)t:([] name:(); iq:())  /创建一个未指定类型的空表
q)t1:([] name:`symbol$(); iq:`int$())  /创意一个指定类型的空表
q)t2:([] name:0#`; iq:0#0)  /创意一个指定类型的空表,0#`表示指定name字段为symbol类型,0#0表示指定iq字段为int类型
q)t,:`zhagnsan,99.9  /为表t中添加数据,这里添加的name为symbol类型,iq字段为float类型,
/因此后面name字段只能添加symbol类型的数据,iq字段只能添加float类型的数据
q)t  /查看表t中的数据
name  iq
-------------
zhagnsan 99.9
q)t,:`lisi,98  /当我们为表t中添加的数据中的iq字段不为folat类型时会报错
'type
q)t,:`lisi,98.0  /添加成功
q)t
name  iq
-------------
zhagnsan 99.9
lisi  98
q)t1,:`zhangsan,98.1  /表t1的iq字段指定的类型为int,因此添加float类型也会报错
q)t1,:`zhangsan,98  /成功添加对应类型的数据
q)t1
name  iq
-----------
zhangsan 98
q)t2,:`wangwu,100
q)t2
name  iq
----------
wangwu 100

三、表的主键与外键

与MySQL等数据库相似,很多表都可以有主键与外键,KDB+的表也支持主键与外键,而且使用上也更加的灵活。在其他数据库中,主键和外键的值一般是唯一的,但是KDB+中表的主键和外键的值可以不唯一,这是因为KDB+作为时序数据库,所有的值都是有顺序的,这也是它的一个特性。

1. 主键

创建含有主键的表的语法如下:

table_primary:([p 1:v 1 ; ...; p n:v n] c 1:L 1 ; ...; c n:L n)

这里[p 1v 1 ; ...; p nv n]为表table_primary的主键,同时主键可以是多个;

c 1L 1 ; ...; c nL n为表其他值。

q)kt:([eid:1001 1002 1003] name:`Dent`Beeblebrox`Prefect; iq:98 42 126) /创建还有一个主键的表kt。
q)kt  /查看表还有主键kt,我们可以看到主键列与普通列之间有“|”分隔
eid | name  iq
----| --------------
1001| Dent  98
1002| Beeblebrox 42
1003| Prefect  126
q)ktempty:([eid:()] name:(); iq:())  创建含有主键的空表方式一
q)ktempty
eid| name iq
---| -------
q)ktempty1:([eid:`int$()] `symbol$name:(); iq:`int$())  /创建含有主键的空表方式二
q)ktempty1
eid| name iq
---| -------
q)ktempty2:([eid:0#0] name:0#`; iq:0#0)  /创建含有主键的空表方式三
q)ktempty2
eid| name iq
---| -------

我们也可以通过先创建一个普通表,后续增加主键,具体如下:

q)v:([] name:`Dent`Beeblebrox`Prefect; iq:98 42 126) /穿件一个普通表v
q)v
name  iq
--------------
Dent  98
Beeblebrox 42
Prefect  126
q)k:([] eid:1001 1002 1003)  /创建一个普通表k
q)k
eid
----
1001
1002
1003
q)kt:k!v  /将表k指定为表v的主键,利用!操作符
q)kt
eid | name  iq
----| --------------
1001| Dent  98
1002| Beeblebrox 42
1003| Prefect  126
q)ktc:([lname:`Dent`Beeblebrox`Prefect; fname:`Arthur`Zaphod`Ford]; iq:98 42 126) /创建复合主键
q)ktc
lname  fname | iq
-----------------| ---
Dent  Arthur| 98
Beeblebrox Zaphod| 42
Prefect  Ford | 126
q)ktc1:([lname:`symbol$();fname:`symbol$()] iq:`int$())  /创建含有复合主键的空表方式一
q)ktc1
lname fname| iq
-----------| --
q)ktc2:([lname:0#`;fname:0#`] iq:0#0)  /创建含有复合主键的空表方式二
q)ktc2
lname fname| iq
-----------| --

2. 外键

在SQL中的外键是一个表中的列,其值是另一个表中主键列的成员。外键是用于在表之间建立关系的机制。

外键的一个重要特点是,RDBMS实施参照完整性,这意味着外键列的值要求是在相关主键列。在插入具有不存在的外键字段值的行之前,必须首先确保在相关表中存在具有该主键的行。

Q语言中的外键与我们前面讲的枚举的一个应用。

现在假设我们有张包含主键的旅行者的表kt(包含eid编号,名字和智商iq)和一张包含每个每位成员的一个重复智商测试表info_table(包含eid编号和每次测试成绩sc)

q)kt:([eid:1001 1002 1003] name:`Dent`Beeblebrox`Prefect; iq:98 42 126)
q)kt
eid | name  iq
----| --------------
1001| Dent  98
1002| Beeblebrox 42
1003| Prefect  126
q)info_table:([] eid:1003 1001 1002 1001 1002 1001; sc:126 36 92 39 98 42)
q)info_table
eid  sc
--------
1003 126
1001 36
1002 92
1001 39
1002 98
1001 42

为了让智商测试表的每个eid编号都在旅行者的表kt中,我们可以将kt表的主键eid设置为智商测试表中的eid的一个外键,这样只有当向智商测试表中增加的eid编号在旅行者表的中的eid中包含此编号时才能添加成功,否则会报错。(为了方便对比,我们新建一个智商测试表info_table_foreign)

q)info_tables_foreign:([] eid:`kt$1003 1001 1002 1001 1002 1001; sc:126 36 92 39 98 42)  /创建含有外键的表,
/这里eid:`kt$1003 1001 1002 1001 1002 1001;表示info_tables_foreign表的eid列参考表kt的主键eid列。
/`kt$value也是我们前面介绍的枚举的操作方法。
q)info_tables_foreign
eid  sc
--------
1003 126
1001 36
1002 92
1001 39
1002 98
1001 42
q)meta info_tables_foreign  /我们可以通过meta函数来查询表info_tables_foreign的一个结构信息,
/我们看到f栏中有kt,表示该表有个外键,并且对应的表是kt这张表
c  | t f a
---| ------
eid| j kt
sc | j
q)info_tables_foreign,:11111,99  /这时我们往表中插入一条kt表的eid中不包含的11111编号,发现插入不成功。
'cast
q)info_tables_foreign,:1003,99  /这时我们往表中插入一条kt表的eid中包含的1003编号,插入成功。
q)info_tables_foreign
eid  sc
--------
1003 126
1001 36
1002 92
1001 39
1002 98
1001 42
1003 99
q)info_tables,:11111,99  /我们往不好含外键的表中插入新的11111编号会成功,因为它是一张独立的表
q)info_tables
11111 99

3. 基本操作

我们可以通过key函数查询一个表中的主键;通过value函数查询除去主键的其他值;keys函数只返回主键的名称(不显示主键的值);cols函数查询一个表的所有列的名称,xkey函数来指定普通列转变为一个主键列或将一个主键列转为普通列;也可以通过!操作符来指定或者取消主键列;fkeys函数来返回外键的名称。具体操作方式如下:

q)kt
eid | name  iq
----| --------------
1001| Dent  98
1002| Beeblebrox 42
1003| Prefect  126
q)key kt
eid
----
1001
1002
1003
q)value kt
name  iq
--------------
Dent  98
Beeblebrox 42
Prefect  126
q)keys kt
,`eid
q)cols kt
`eid`name`iq
q)t:([] eid:1001 1002 1003; name:`Dent`Beeblebrox`Prefect; iq:98 42 126)
q)t
eid  name iq
-------------------
1001 Dent  98
1002 Beeblebrox 42
1003 Prefect  126
q)`eid xkey t
eid | name  iq
----| --------------
1001| Dent  98
1002| Beeblebrox 42
1003| Prefect  126
q)`name xkey t
name  | eid iq
----------| --------
Dent  | 1001 98
Beeblebrox| 1002 42
Prefect  | 1003 126
q)`eid`name xkey t
eid  name | iq
---------------| ---
1001 Dent  | 98
1002 Beeblebrox| 42
1003 Prefect  | 126
q)kt
eid | name  iq
----| --------------
1001| Dent  98
1002| Beeblebrox 42
1003| Prefect  126
q)() xkey kt
eid  name iq
-------------------
1001 Dent  98
1002 Beeblebrox 42
1003 Prefect  126
q)t
eid  name iq
-------------------
1001 Dent  98
1002 Beeblebrox 42
1003 Prefect  126
q)1!t
eid | name  iq
----| --------------
1001| Dent  98
1002| Beeblebrox 42
1003| Prefect  126
q)2!t
eid  name | iq
---------------| ---
1001 Dent  | 98
1002 Beeblebrox| 42
1003 Prefect  | 126
q)kt
eid | name  iq
----| --------------
1001| Dent  98
1002| Beeblebrox 42
1003| Prefect  126
q)0!kt
eid  name iq
-------------------
1001 Dent  98
1002 Beeblebrox 42
1003 Prefect  126
q)info_tables_foreign
eid  sc
--------
1003 126
1001 36
1002 92
1001 39
1002 98
1001 42
1003 99
q)meta info_tables_foreign
c  | t f a
---| ------
eid| j kt
sc | j
q)fkeys info_tables_foreign
eid| kt

四、表的基本操作(虚拟列)

说到数据库,我们首先想到的就是增删改查,这里我们简单介绍一下表的基本操作,下一个主题我将会专门来分享一下表的详细的增删改查的操作。

1. 查询

  • 1) count函数可以查询一个表有多少行数据;
  • 2) select函数可以查询表中的具体数据;
  • 3) 我们也可以用字典的查询方式来操作表,但是返回的结果是字典。
q)t:([] name:`Dent`Beeblebrox`Prefect; iq:98 42 126)
q)t
name  iq 
--------------
Dent  98 
Beeblebrox 42 
Prefect  126
q)count t  /使用count函数可以查看表t中有多少行数据
3
q)t  /表的第一种查询方式,适合小数据
name  iq 
--------------
Dent  98 
Beeblebrox 42 
Prefect  126
q)t[0]  /利用字典或者列表的索引方式,查询表t的第一行数据
name| `Dent
iq  | 98
q)s:t[0]
q)s
name| `Dent
iq  | 98
q)type s  /可以看处利用字典这样的索引方式返回的结果是字典
99h
q)type t
98h
q)select from t  /使用select查询,这里是查询所有类容,类似于前面的直接输入一个t返回的结果
name  iq 
--------------
Dent  98 
Beeblebrox 42 
Prefect  126
q)select name from t  /查询表t中name字段的所有内容
name  
----------
Dent  
Beeblebrox
Prefect  

2. 增添

前面介绍多,给表中增加数据与字典中增加数据一样,使用,:操作符就可以快速增添新的数据。

q)t
name  iq 
--------------
Dent  98 
Beeblebrox 42 
Prefect  126
q)t,:`wangwu,99  /通过,:操作符来给表t中增添数据,不报错就是添加成功
q)t
name  iq 
--------------
Dent  98 
Beeblebrox 42 
Prefect  126
wangwu  99

3. 删除

删除也是使用delete,与SQL相似。

q)t
name  iq 
--------------
Dent  98 
Beeblebrox 42 
Prefect  126
wangwu  99 
q)delete name from t  /删除表t中的name字段
iq 
---
98 
42 
126
99

4. 更新

更新使用update,也是与SQL类似。

q)update iq:199 from t where name=`wangwu  /这里我们想修改name是王五的iq为199,这里不能写成iq=99,Q语言的赋值都是:操作符
name  iq 
--------------
Dent  98 
Beeblebrox 42 
Prefect  126
wangwu  199

5. 合并

有时候我们可能会涉及将两个表进行合并,合并有“,”合并与“^” 合并,“,”

q)t,`name`iq!(`lisi;`123)  /“,”合并与上面讲的,:增添很类似,至于不会进行数据类型检查,这里`123为symbol类型,而不是int类型也能添加成功
name  iq 
---------------
Dent  98 
Beeblebrox 42  
Prefect   126 
wangwu  99  
lisi  `123
q)t,([] name:1#`w; iq:1#26)  /这里1#`w的含义就是产生一个`w,2#`w就是产生两个`w`w
name  iq 
--------------
Dent  98 
Beeblebrox 42 
Prefect  126
wangwu  99 
w  26
q)t,([] iq:1#42; name:`W)  /列不对应,但是名称相同也会合并成功
name  iq 
--------------
Dent  98 
Beeblebrox 42 
Prefect  126
wangwu  99 
W  42 
q)t,([] iq:1#`w; name:`W)
name  iq 
--------------
Dent  98 
Beeblebrox 42 
Prefect  126
wangwu  99 
W  `w
q)kt:([eid:1001 1002 1003] name:`Dent`Beeblebrox`Prefect; iq:98 42 126)
q)kt
eid | name  iq 
----| --------------
1001| Dent  98 
1002| Beeblebrox 42 
1003| Prefect  126
q)kt,([eid:1003 1004] name:`Prefect`W; iq:150 26)  /当合并时两边有相同的数据时,右边的会替换左右的元表中的数据
eid | name  iq 
----| --------------
1001| Dent  98 
1002| Beeblebrox 42 
1003| Prefect  150
1004| W  26
q)([k:`a`b`c] v:10 0N 30)^([k:`a`b`c] v:100 200 0N)  /^合并以右边的为主,缺少项(0N)则会用左边表中的数据填补
k| v  
-| ---
a| 100
b| 200
c| 30 
q)([k:`a`b`c`x] v:10 0N 30 40)^([k:`a`b`c`y]; v:100 200 0N 0N)
k| v  
-| ---
a| 100
b| 200
c| 30 
x| 40 
y| 0N
q)([] c1:`a`b`c),'([] c2:100 200 300)
c1 c2 
------
a  100
b  200
c  300
q)([] c1:`a`b`c; c2:1 2 3),'([] c2:100 200 300)
c1 c2 
------
a  100
b  200
c  300
q)([k:1 2 3] v1:10 20 30),'([k:3 4 5] v2:1000 2000 3000) /注意仔细理解这里的链接方式
k| v1 v2  
-| -------
1| 10  
2| 20  
3| 30 1000
4|  2000
5|  3000

五、复杂的数据列

Q语言中的表还具有特殊性,前面我们介绍过列表(list)、字典(dictionary),字典是列表的特殊方式,而表(table)又是字典的特殊方式,因此表就有一种特殊的形式了,因此某个列或者某个value中的数值可以包含多个值,所以当前整个字段就变成了嵌套列表,当然我们还是推荐简单列表,这样的处理速度更快,这才是Q语言的本质。

下面举个例子,对于股票书籍,我们每天可能会记录一个开盘价和收盘价,则可以这样记录:

q)tm:([] date:2015.01.01 2015.01.08; stock_name:`Apple`IBM; Price_change:(38.92 67.34; 16.99 31.69))
q)tm
date  stock_name Price_change
------------------------------------------------------
2015.01.01 Apple  38.92 67.34 
2015.01.08 IBM  16.99 31.69

可能还有一些时候我们会记录一些更加复杂的数据,比如:

q)tm1:([] wk:2015.01.01 2015.01.08; rv:(38.92 67.34; 16.99 5.14 128.23 31.69)) 
q)tm1
wk  rv  
----------------------------------
2015.01.01 38.92 67.34  
2015.01.08 16.99 5.14 128.23 31.69

这里我们的rv列就是一个复杂的数据列,我们对复杂的数据列也有特殊的操作方式,如:

q)select wk, srt:desc each rv, avgr:avg each rv, hi:max each rv from tm1  
/desc each rv表示将rv字段的每个格子的值降序排列,由于rv字段不是简单列表,因此要用到each
/ avg each rv表示求rv字段每一个格子中的平均值
/ max each rv表示返回rv字段每一个格子中的最大值
wk  srt  avgr  hi 
-------------------------------------------------
2015.01.01 67.34 38.92  53.13  67.34 
2015.01.08 128.23 31.69 16.99 5.14 45.5125 128.23
q)select wk, drp:neg 1_'deltas each desc each rv from tm1
/ neg 1_'deltas each desc each rv表示求rv字段的每个格子中的值的增量值,并降序排列
wk  drp  
---------------------------
2015.01.01 ,28.42  
2015.01.08 96.54 14.7 11.85

六、表的属性与操作

我们可以给表中的一些字段添加一些特殊属性(应用到#的重载操作),非常类似于SQL中的约束条件,但是在Q语言中这写属性不是结构性的,而是描述性的,意思是添加了这些属性后,Q语言只会去检查是否满足这些属性,但是并不会去让解释器将添加了属性的字段强制变成这个属性。比如添加一个属性到某个字段字段是增序排列,如果不是增序排列,并不会将结果变成增序排列。具体可以参考下面的案例。

这里我们互主要介绍一下排序(s#),唯一(u#),parted(p#),分组(g#)和删除属性

q)`s#1 2 4 8  /给一个列表添加降序(`s)属性
`s#1 2 4 8
q)`s#2 1 3 4
's-fail
q)asc 2 1 8 4  / 这里我们可以看出`s属性与sac操作返回结果是一样的
`s#1 2 4 8
q)til 5
0 1 2 3 4
q)L:`s#1 2 3 4 5
q)L,:6
q)L
`s#1 2 3 4 5 6
q)L,:0  /当我们给一个有`s属性的列表添加一个会破坏该属性的值时,该列表的`s属性就会消失
q)L
1 2 3 4 5 6 0
q)t:([] ti:`s#00:00:00 00:00:01 00:00:03; v:98 98 100.)  /我们给表中的某一个字段添加`s属性
q)t
ti  v 
------------
00:00:00 98 
00:00:01 98 
00:00:03 100
q)meta t  /这时候我们就可以通过meta来查看表t的属性,a字段就出现了s的标识
c | t f a
--| -----
ti| v  s
v | f  
q)meta `s#([] ti:00:00:00 00:00:01 00:00:03; v:98 98 100.)
c | t f a
--| -----
ti| v  p
v | f  
q)meta `s#([k:1 2 3 4] v:`d`c`b`a)
c| t f a
-| -----
k| j  s
v| s  
q)`u#2 1 4 8  /`u的属性是让列表中的数据保持唯一性
`u#2 1 4 8
q)`u#2 1 4 8 2  /当该列表的每个数据不具有唯一性时就会报错
'u-fail
q)L:`u#2 1 4 8
q)L,:3
q)L
`u#2 1 4 8 3
q)L,:2  /当为列表中添加的数据列表中已经包含了的时候就会使该列表失去唯一的属性
q)L
2 1 4 8 3 2 
q)`p#2 2 2 1 1 4 4 4 4 3 3
`p#2 2 2 1 1 4 4 4 4 3 3
q)`p#2 2 2 1 1 4 4 4 4 3 3 6  /`p属性就是检查后面的数据是否在前面出现过,如果出现则就会报错,
/但是可以连续出现,如222,222111都可以,但是不能2221112这样的
`p#2 2 2 1 1 4 4 4 4 3 3 6
q)`p#2 2 2 1 1 4 4 4 4 3 3 6 1
'u-fail
q))`p#2 2 2 1 1 4 4 4 4 3 3 6 2
'u-fail
q)`g#1 2 3 2 3 4 3 4 5 2 3 4 5 4 3 5 6
`g#1 2 3 2 3 4 3 4 5 2 3 4 5 4 3 5 6
q)L:`s#til 10
q)L
`s#0 1 2 3 4 5 6 7 8 9
q)`#L  /通过`#操作就可以直接去掉属性
0 1 2 3 4 5 6 7 8 9
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容

  • 一、 表的排序 我们知道表的字段中的值其实是由列表组成,因此具有固有的顺序。但是我们也可以进行排序操作的,只是Q语...
    Hero_cxs阅读 367评论 0 0
  • 前言 Q的表的基本操作与传统数据库的表的操作非常的相似,同时Q的表的操作还有一些传统数据库不具有的高级操作。但是可...
    Hero_cxs阅读 1,021评论 0 0
  • ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。 O...
    我想起个好名字阅读 5,169评论 0 9
  • 前言 由于项目组里的老大工程能力实在太强,各种技术栈玩得6到飞起,于是我们也跟着开阔了不少视野。业务的一些特性也导...
    yanianthe阅读 12,296评论 1 8
  • 目录 1、主键、外键、索引定义 2、为什么定义主键、外键 3、主键和外键的关系 4、数据库中主键和外键的设计原则 ...
    greensure阅读 1,796评论 1 4