Oracle Datatypes

Character Datatypes

NLS parameters (V$NLS_PARAMETERS)

  • NLS_LENGTH_SEMANTICS
    1. BYTE (default)
    2. CHAR
  • NLS_CHARACTERSET
    Character encoding of CHAR, VARCHAR2 and CLOB datatypes
    eg: AL32UTF8 (UTF8 not recommended)
    1. Latin characters -> 1 byte
    2. Chinese characters(in BMP) -> 3 bytes
  • NLS_NCHAR_CHARACTERSET
    Character encoding of NCHAR, NVARCHAR2 and NCLOB datatypes
    eg: AL16UTF16 (UTF8 not recommended)
    1. Latin characters -> 2 bytes
    2. Chinese characters(in BMP) -> 2 bytes

Char

  • Store character data encoded by NLS_CHARACTERSET

  • Char(2000 byte)
    We can store up to 666 Chinese characters(666 * 3 = 1998 bytes) and 2 Latin characters(2 * 1 = 2 bytes).

  • Char(n char)
    We can store n chars as long as the length of encoded chars <= 2000 bytes

    1. 0 < n <= 666
      We can store n(bytes = 3*n <= 1998) Chinese chars.
    2. 666 < n <= 2000
      You can't store n(bytes = 3*n > 2000) Chinese chars.

VarChar2

  • Store character data encoded by NLS_CHARACTERSET

  • MAX_STRING_SIZE

    1. STANDARD 4000 bytes
    2. EXTENDED 32767 bytes
  • VarChar2(4000 byte)
    We can store up to 1333 Chinese characters(1333 * 3 = 3999 bytes) and 1 Latin characters(1 * 1 = 1 bytes).

  • VarChar2(n char)
    We can store n chars as long as the length of encoded chars <= 4000 bytes

    1. 0 < n <= 1333
      We can store n(bytes = 3*n <= 3999) Chinese chars.
    2. 1333 < n <= 4000
      You can't store n(bytes = 3*n > 2000) Chinese chars.

NChar

  • Store unicode character data encoded by NLS_NCHAR_CHARACTERSET

For a Unicode Standard-enabled database(NLS_CHARACTERSET is set to AL32UTF8), we can also use datatype char to store unicode character data. NChar is NOT the preferred option to store unicode character data.

NVarChar2

  • Store unicode character data encoded by NLS_NCHAR_CHARACTERSET
  • MAX_STRING_SIZE
    1. STANDARD 4000 bytes
    2. EXTENDED 32767 bytes

For a Unicode Standard-enabled database(NLS_CHARACTERSET is set to AL32UTF8), we can also use datatype VarChar2 to store unicode character data. NVarChar is NOT the preferred option to store unicode character data.

Internal Storage

We can use dump function to inspect how data is stored.

Sample output Typ=96 Len=5: 230,177,137,49,32
Typ=96 represent data type is Char
Len=5 represent data is stored by 5 bytes
'230,177,137,49,32' represent the actual data

DROP TABLE zz_char;

CREATE TABLE zz_char (
   char_b_1       CHAR(5 BYTE),
   varchar2_b_1   VARCHAR2(4000 BYTE),
   nchar_1        NCHAR(5),
   nvarchar2_1    NVARCHAR2(2000)
);

INSERT INTO zz_char (
   char_b_1,
   varchar2_b_1,
   nchar_1,
   nvarchar2_1
) VALUES (
   '漢1',
   '漢2',
   '字3',
   '字4'
);

SELECT char_b_1, dump(char_b_1),
       varchar2_b_1, dump(varchar2_b_1),
       nchar_1, dump(nchar_1),
       nvarchar2_1, dump(nvarchar2_1)
FROM zz_char;
Datatype Characters Encoding Dump
char(5 byte) 漢1 AL32UTF8 Typ=96 Len=5: 230,177,137,49,32
varchar2(4000 byte) 漢2 AL32UTF8 Typ=1 Len=4: 230,177,137,50
nchar(5) 字3 AL16UTF16 Typ=96 Len=10: 91,87,0,51,0,32,0,32,0,32
nvarchar2(2000) 字4 AL16UTF16 Typ=1 Len=4: 91,87,0,52
  • 漢1 -> AL32UTF8 (230,177,137,49,32)
    230,177,137 -> 11100110 10110001 10001001 -> 11100110 10110001 10001001 -> 0110 1100 0100 1001 -> 0x 6C 49 -> 漢
    49 -> character 1
    32 -> blank character(blank-padded)

  • 字3 -> AL16UTF16(91,87,0,51,0,32,0,32,0,32)
    91,87 -> 0x 5B 57 -> 字
    0,51 -> character 3
    0,32,0,32,0,32 -> 3 blank characters(blank-padded)

Character Datatypes Summary

Char VarChar2 NChar NVarChar2
Definition char(n [byte|char]) varchar2(n [byte|char]) nchar(n) nvarchar2(n)
Fixed-Variable Fixed Variable Fixed Variable
Length Semantics byte(default) char byte(default) char char char
Range in Bytes 1~2000 1~4000 1~2000 1~4000
Character Encoding AL32UTF8 AL32UTF8 AL16UTF16 AL16UTF16
Maximum Latin Chars 2000 4000 1000 2000
Maximum Chinese Chars(BMP) 666 (2000/3) 1333 (4000/3) 1000 2000

Numeric Datatypes

Number Datatype

  • Number[(p[,s])]
  • p - Precision(total number of digits) (1~38)
  • s - Scale(number of digits to the right of decimal point) (-84~127)
  • 1~21 bytes (see dump in Internal Numeric Format section)
  • Fixed-point Number(p,s)
  • Floating-point Number
N Number(p,s) Stored As
123.45 Number 123.45
123.45 Number(3) 123
123.45 Number(3,1) exceeds precision
123.45 Number(3,-1) 120
123.45 Number(3,-2) 100
123.45 Number(3,-3) 0
123.45 Number(3,-4) 0
123.45 Number(5) 123
123.45 Number(5,1) 123.5
123.45 Number(5,2) 123.45
123.45 Number(5,3) exceeds precision
0.012 Number(2,3) 0.012

Internal Storage

SELECT '9.9999999999999999999999999999999999999e125',
       dump(9.9999999999999999999999999999999999999E125),
       '1e-130',
       dump(1E-130),
       '-1e-130',
       dump(-1E-130),
       '-9.9999999999999999999999999999999999999e125',
       dump(-9.9999999999999999999999999999999999999E125),
       0,
       dump(0),
       utl_raw.cast_to_number('FF65'),
       dump(utl_raw.cast_to_number('FF65') ),
       utl_raw.cast_to_number('00'),
       dump(utl_raw.cast_to_number('00') )
FROM dual;
N DUMP(N) Description
9.99...9e125
(9 repeated 38 times)
Typ=2 Len=20: 255,100,...,100
(100 repeated 19 times)
Maximum Positive
1e-130 Typ=2 Len=2: 128,2 Minimum Positive
-1e-130 Typ=2 Len=3: 127,100,102 Maximum Negative
-9.99...9e125
(9 repeated 38 times)
Typ=2 Len=21: 0,2,...,2,102
(2 repeated 19 times)
Minimum Negative
0 Typ=2 Len=1: 128 Zero
utl_raw.cast_to_number('FF65') Typ=2 Len=2: 255,101 Infinity
utl_raw.cast_to_number('00') Typ=2 Len=1: 0 -Infinity
  • Positive Number 12345.6789
    Typ=2 Len=6: 195,2,24,46,68,90

    1. First byte 195 -> 1100 0011
      Sign -> positive, the first bit is 1
      Exponent -> 3, the following 7 bits (100 0011) - 64 (100 0000) = 3
    2. The other data (2,24,46,68,90) subtract 1
      01, 23, 45, 67, 89
    3. Get the result
      0.0123456789*100^3 = 12345.6789
  • Negative Number -12345.6789
    Typ=2 Len=7: 60,100,78,56,34,12,102

    1. First byte 60 -> 0011 1100
      Sign -> negative, the first bit is 0
      Exponent -> 3, the following 7 bits (011 1100) transfer to ones’ complement (100 0011) - 64 (100 0000) = 3

    2. 100 subtract each of (100,78,56,34,12) then plus 1
      The last byte is 102 for every negative number (exclude it)
      01, 23, 45, 67, 89

      • Why 102? -2 > -2.0001 and 62,99,102 > 62,99,101,100,102


        Why 102?.png
    3. Get the result
      -0.0123456789*100^3 = -12345.6789

  • Zero, Infinite, -Infinite

Float Datatype

  • Float[(p)]
  • p - binary precision (1-126)
  • binary precision * 0.30103 = decimal precision (digits = ceil(bits / log(2,10))
Float(n) Float Value(1/3) Number(n) Number Value(1/3)
Float(1~3) 0.3 Number(1) 0.3
Float(4~6) 0.33 Number(2) 0.33
Float(126) 0.3...3(3 repeated 38 times) Number(38) 0.3...3(3 repeated 38 times)

Binary_Float Datatype

  • Single-precision floating-point
  • 5 bytes (4 data bytes + 1 length byte)

Internal Storage

IEEE754 Format wiki

wiki 4 bytes float - bits

wiki 4 byte float - result formula
  1. Sign (-1) ^ b31 = (-1) ^ 0= (+1)
  2. Exponent b30...b23 (0111 1100) = 124
  3. (1.b22...b0)2 = 1 + b22 ^(-1) + b21^(-2) + ... + b0^(-23) = 1 + 1^(-2) = 1.25
  4. Result = (+1) * 2 ^(124-127) * 1.25 = 0.15625

Oracle Format

select dump(0.15625f,16) from dual;
Typ=100 Len=4: be,20,0,0
Binary format 1011 1110 0010 0000 0000 0000 0000 0000

The first bit(sign bit) is different from IEEE754 format, all other bits are identical.

Binary_Double Datatype

  • Double-precision floating-point
  • 9 bytes (8 data bytes + 1 length byte)

Internal Storage

IEEE754 Format wiki

wiki 8 bytes double - bits

wiki 8 bytes double - result formula

Numeric Datatypes Summary

Datatype Precision Value Positive Range Negative Range
Number Decimal(0-9) extract 1.0E-130 ~ 1.0E126(not inclusive) -1.0E126(not inclusive) ~ -1.0E-130
Float Binary(0-1) extract 1.0E-130 ~ 1.0E126(not inclusive) -1.0E126(not inclusive) ~ -1.0E-130
Binary_Float Binary(0-1) approximate 1.17549E-38F ~ 3.40282E+38F -3.40282E+38F ~ -1.17549E-38F
Binary_Double Binary(0-1) approximate 2.22507485850720E-308 ~ 1.79769313486231E+308 -1.79769313486231E+308 ~ -2.22507485850720E-308

Date Datatypes

Alter date/timestamp/timestamp with tz format.
alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss';
alter session set nls_timestamp_format = 'yyyy-mm-dd hh24:mi:ssxff';
alter session set nls_timestamp_tz_format = 'yyyy-mm-dd hh24:mi:ssxff tzr';

Datetime Datatypes

Date

Timestamp

  • Timestamp[(fractional_seconds_precision)]
  • fractional_seconds_precision (0-9, default 6)

Timestamp with time zone

  • TIMESTAMP [(fractional_seconds_precision)] WITH TIME ZONE
  • fractional_seconds_precision (0-9, default 6)

Timestamp with local time zone

  • TIMESTAMP [(fractional_seconds_precision)] WITH LOCAL TIME ZONE
  • fractional_seconds_precision (0-9, default 6)

Internal Storage and Summary

DROP TABLE zz_date;

CREATE TABLE zz_date (
   date_1        DATE,
   timestamp_1   TIMESTAMP(9),
   timestamp_2   TIMESTAMP(9) WITH TIME ZONE,
   timestamp_3   TIMESTAMP(9) WITH LOCAL TIME ZONE
);

INSERT INTO zz_date (
   date_1,
   timestamp_1,
   timestamp_2,
   timestamp_3
) VALUES (
   ( '2019-03-04 17:30:40' ),
   ( '2019-03-04 17:30:40.000000256' ),
   ( '2019-03-04 17:30:40.000000512 +08:00' ),
   ( '2019-03-04 17:30:40.000001024' )
);

SELECT date_1,
       dump(date_1),
       timestamp_1,
       dump(timestamp_1),
       timestamp_2,
       dump(timestamp_2),
       timestamp_3,
       dump(timestamp_3)
FROM zz_date;
Date Timestamp Timestamp TZ Timestamp LTZ
Value 2019-03-04 17:30:40 2019-03-04 17:30:40.000000256 2019-03-04 17:30:40.000000512 +08:00 2019-03-04 17:30:40.000001024
Dump Typ=12 Len=7: 120,119,3,4,18,31,41 Typ=180 Len=11: 120,119,3,4,18,31,41,0,0,1,0 Typ=181 Len=13: 120,119,3,4,10,31,41,0,0,2,0,28,60 Typ=231 Len=11: 120,119,3,4,10,31,41,0,0,4,0
Length 7 bytes 11 bytes 13 bytes 11 bytes
Century 1st byte 120
20 = 120 - 100
<< << <<
Year in century 2nd byte 119
19 = 119 - 100
<< << <<
Month 3rd byte
3
<< << <<
Day 4th byte
4
<< << <<
Hour 5th byte 18
17 = 18 - 1
<< << <<
Minute 6th byte 31
30 = 31 - 1
<< << <<
Second 7th byte 41
40 = 41 - 1
<< << <<
Nanosecond - 8~11th bytes 0,0,1,0
256 = 0x 00 00 01 00
8~11th bytes 0,0,2,0
512 = 0x 00 00 02 00
8~11th bytes 0,0,4,0
1024 = 0x 00 00 04 00
Timezone hour - - 12th byte 28
8 = 28 - 20
-
Timezone minute - - 13th byte 60
0 = 60 - 60
-

Interval Datatypes

Interval year to month

  • INTERVAL YEAR [(year_precision)] TO MONTH
  • year_precision (0-9, default 2)

Interval day to second

  • INTERVAL DAY [(day_precision)] TO SECOND [(fractional_seconds_precision)]
  • day_precision (0-9, default 2)
  • fractional_seconds_precision (0-9, default 6)

Internal Storage and Summary

DROP TABLE zz_interval;

CREATE TABLE zz_interval (
   timestamp_1       TIMESTAMP(9),
   interval_year_1   INTERVAL YEAR(9) TO MONTH,
   interval_day_1    INTERVAL DAY(9) TO SECOND(9)
);

INSERT INTO zz_interval ( timestamp_1, interval_year_1, interval_day_1 ) VALUES (
   ( '2019-03-05 17:30:40.000000256' ),
   INTERVAL '+100-2' YEAR ( 9 ) TO MONTH,
   INTERVAL '10 1:2:3.000000001' DAY TO SECOND ( 9 )
);

INSERT INTO zz_interval ( timestamp_1, interval_year_1, interval_day_1 ) VALUES (
   ( '2019-03-05 17:30:40.000000256' ),
   to_yminterval('100-2'),
   to_dsinterval('10 1:2:3.000000001')
);

SELECT timestamp_1,
       timestamp_1 + interval_year_1,
       timestamp_1 + interval_day_1,
       dump(interval_year_1),
       dump(interval_day_1)
FROM zz_interval;
Interval year to month Interval day to second
Literal value INTERVAL '+100-2' YEAR ( 9 ) TO MONTH INTERVAL '10 1:2:3.000000001' DAY TO SECOND ( 9 )
To_interval value to_yminterval('100-2') to_dsinterval('10 1:2:3.000000001')
Dump Typ=182 Len=5: 128,0,0,100,62 Typ=183 Len=11: 128,0,0,10,61,62,63,128,0,0,1
Length 5 bytes 11 bytes
Description A interval of 100 years and 2 months A interval of 10d,1h,2m,3s and 1 nanosecond
Year 1~4th bytes 128,0,0,100
100 = 0x(80 00 00 64) - 0x(80 00 00 00)
-
Month 5th byte 62
2 = 62 - 60
-
Day - 1~4th bytes 128,0,0,10
10 = 0x(80 00 00 0A) - 0x(80 00 00 00)
Hour - 5th byte 61
1 = 61 - 60
Minute - 6th byte 62
2 = 62 - 60
Second - 7th byte 63
3 = 63 - 60
Nanosecond - 8~11th bytes 128,0,0,1
1 = 0x(80 00 00 01) - 0x(80 00 00 00)

LOB Datatypes

  • Create file /tmp/abc.txt in database server file system
    sh-4.2# echo 123456 > /tmp/abc.txt
  • Create oracle directory object
    CREATE DIRECTORY TMP_DIR AS '/tmp';
  • Create lob table
CREATE TABLE zz_lob (
   lob_id    NUMBER,
   clob_1    CLOB,
   nclob_1   NCLOB,
   blob_1    BLOB,
   bfile_1   BFILE
);

CLOB

  • Store large object data of characters encoded by NLS_CHARACTERSET
  • Maximum size is (4 gigabytes - 1) * (database block size)
INSERT INTO zz_lob ( clob_1 ) VALUES (to_clob('123'));

NCLOB

  • Store large object data of unicode character encoded by NLS_NCHAR_CHARACTERSET
  • Maximum size is (4 gigabytes - 1) * (database block size)
INSERT INTO zz_lob ( nclob_1 ) VALUES (to_nclob('123'));

BLOB

  • Store binary large object(image, video, audio..)
  • Maximum size is (4 gigabytes - 1) * (database block size)

Store BLOB

DECLARE
   src_lob    BFILE := bfilename('TMP_DIR', 'abc.txt');
   dest_lob   BLOB;
BEGIN
   INSERT INTO zz_lob ( lob_id, blob_1 ) VALUES ( 2, empty_blob() ) RETURNING blob_1 INTO dest_lob;
   dbms_lob.open(src_lob, dbms_lob.lob_readonly);
   dbms_lob.loadfromfile(
      dest_lob   => dest_lob,
      src_lob    => src_lob,
      amount     => dbms_lob.getlength(src_lob)
   );
   dbms_lob.close(src_lob);
   COMMIT;
END;

BFILE

  • Store a BFILE locator which points to a binary file in file system outside the database
  • The BFILE locator (directory name and file name)
  • Maximum size of BFILE is 4 gigabytes

Store BFILE

  • bfilename
INSERT INTO zz_lob ( lob_id, bfile_1 ) VALUES (
   1,
   bfilename('TMP_DIR', 'abc.txt')
);
  • Read BFILE by dbms_lob api
DECLARE
   fil   BFILE;
   pos   NUMBER := 1;
   bat   NUMBER := 5;
   buf   RAW(5);
BEGIN
   SELECT bfile_1 INTO fil FROM zz_lob WHERE lob_id = 1;
--   fil:=BFILENAME('TMP_DIR','abc.txt');

   dbms_lob.open(fil, dbms_lob.lob_readonly);

   FOR i IN 1..ceil(dbms_lob.getlength(fil) / bat) LOOP
      pos   := 1 + bat * ( i - 1 );
      dbms_output.put_line('i ' ||  i || ' start ' || pos || ' end ' || (pos + bat) );
      dbms_lob.read(fil, bat, pos, buf);
      dbms_output.put_line(utl_raw.cast_to_varchar2(buf) );
   END LOOP;
   dbms_lob.close(fil);
END;
  • BFILE output
--i 1 start 1 end 6
12345
--i 2 start 6 end 11
6

Other Datatypes

Raw

  • Raw(n)

  • Store binary data/byte string

  • Variable length

  • MAX_STRING_SIZE

    1. STANDARD 2000 bytes
    2. EXTENDED 32767 bytes
DROP TABLE zz_raw;

CREATE TABLE zz_raw (
   raw_1   RAW(5),
   raw_2   RAW(5)
);

DELETE FROM zz_raw;

INSERT INTO zz_raw VALUES (
   utl_raw.cast_to_raw('a'),
   utl_raw.cast_from_number(1)
);

SELECT raw_1,
       dump(raw_1, 16),
       utl_raw.cast_to_varchar2(raw_1),
       raw_2,
       dump(raw_2, 16),
       utl_raw.cast_to_number(raw_2)
FROM zz_raw;
Raw Dump(Raw,16) value
utl_raw.cast_to_raw('a')
0x61
Typ=23 Len=1: 61 utl_raw.cast_to_varchar2
= a
utl_raw.cast_from_number(1)
0xC102
Typ=23 Len=2: c1,2 utl_raw.cast_to_number
= 1

RowId URowId

RowId

Base64 string representing unique physical address of each row in heap-organized table.

  • RowId Type
    RowId type: 0 is restricted, 1 is extended
    dbms_rowid.rowid_type(ROWID)
  • Data Object Number
    The unique indentifier of the object.
    dbms_rowid.rowid_object(ROWID)
  • File Number
    The relative number of the datafile in the tablespace.
    dbms_rowid.rowid_relative_fno(ROWID)
  • Data Block Number
    The relative block number in the datafile.
    dbms_rowid.rowid_block_number(ROWID)
  • Row Number
    The relative rownum within the block.
    dbms_rowid.rowid_row_number(ROWID)

URowId

Base 64 string representing the logical address of a row of an index-organized table.

  • UROWID [(size)]
  • size (4000bytes)

Reference

Oracle Datatypes

Fixed-point and floating-point representations of numbers
Introduction to Fixed Point Number Representation

How numbers are saved in oracle
Oracle dump number

Single-precision_floating-point
Double-precision_floating-point_format

ORAFAQ Data_types

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,143評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,553評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,620評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,416評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,940評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,170評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,709評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,597評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,029評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,407評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,663評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,403評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,746評論 2 370

推薦閱讀更多精彩內容