Spark SQL----數據類型
- 一、支持的數據類型
- 二、浮點特殊值
- 三、正負無窮語義
- 四、NaN語義
- 五、例子
一、支持的數據類型
Spark SQL和DataFrames支持以下數據類型:
- Numeric類型
- ByteType:表示1字節的帶符號整數。數字的范圍從-128到127。
- ShortType:表示2字節有符號整數。數字的范圍從-32768到32767。
- IntegerType:表示4字節有符號整數。數字范圍為-2147483648到2147483647。
- LongType:表示8字節有符號整數。數字范圍從9223372036854775808到9223372036864775807。
- FloatType:表示4字節的單精度浮點數。
- DoubleType:表示8字節雙精度浮點數。
- DecimalType:表示任意精度的帶符號十進制數。內部由java.math.BigDecimal支持。BigDecimal由一個任意精度的integer unscaled值和一個32-bit integer scale組成。
- String類型
- StringType:表示字符串值。
- VarcharType(length):StringType的一個變體,有長度限制。如果輸入字符串超過長度限制,數據寫入將失敗。注意:此類型只能在表schema中使用,不能在函數/運算符中使用。
- CharType(length):VarcharType(length)的一種變體,是固定長度。讀取CharType(n)類型的列總是返回長度為n的字符串值。Char type列比較將把短的列填充到較長長度。
- Binary 類型
- BinaryType:表示字節序列值。
- Boolean 類型
- BooleanType:表示布爾值。
- Datetime類型
- DateType:表示由字段年、月和日的值組成的值,不帶時區。
- TimestampType:帶有本地時區的時間戳(TIMESTAMP_LTZ)。它表示由年、月、天、小時、分鐘和秒字段值組成的值,以及會話本地時區。時間戳值表示一個絕對時間點。
- TimestampNTZType:不帶時區的時間戳(TIMESTAMP_NTZ)。它表示由年、月、日、小時、分鐘和秒字段值組成的值。所有操作都是在不考慮任何時區的情況下執行的。
- 注意:Spark中的TIMESTAMP是用戶指定的別名,與TIMESTAMP_LTZ和TIMESTAMP_NTZ變體之一關聯。用戶可以通過配置spark.sql.timestampType將默認時間戳類型設置為 TIMESTAMP_LTZ(默認值)或TIMESTAMP_NTZ。
- Interval類型
- YearMonthIntervalType(startField,endField):表示由以下字段的連續子集組成的year-month間隔:
- MONTH,年內的月份[0…11],
- YEAR,年份在[0…178956970]范圍內。
單個interval字段是非負的,但interval本身可以有符號,并且是負的。
startField是該類型最左邊的字段,endField是最右邊的字段。startField和endField的有效值分別為0(MONTH)和1(YEAR)。支持的year-month interval 類型有:
- YearMonthIntervalType(startField,endField):表示由以下字段的連續子集組成的year-month間隔:
Year-Month Interval Type | SQL type | An instance of the type |
---|---|---|
YearMonthIntervalType(YEAR, YEAR) or YearMonthIntervalType(YEAR) | INTERVAL YEAR | INTERVAL ‘2021’ YEAR |
YearMonthIntervalType(YEAR, MONTH) | INTERVAL YEAR TO MONTH | INTERVAL ‘2021-07’ YEAR TO MONTH |
YearMonthIntervalType(MONTH, MONTH) or YearMonthIntervalType(MONTH) | INTERVAL MONTH | INTERVAL ‘10’ MONTH |
- DayTimeIntervalType(startField,endField):表示由以下字段的連續子集組成的一天時間interval:
- SECOND,幾分鐘內的秒,可能是一秒的幾分之一[0…59.999999],
- MINUTE,小時內的分鐘[0…59],
- HOUR,天內小時[0…23],
- DAY,在[0…106751991]范圍內的天。
單個interval字段是非負的,但interval本身可以有符號,并且是負的。
startField是該類型最左邊的字段,endField是最右邊的字段。startField和endField的有效值分別為0 (DAY), 1 (HOUR), 2 (MINUTE), 3 (SECOND)。支持的day-time interval類型包括:
Day-Time Interval Type | SQL type | An instance of the type |
---|---|---|
DayTimeIntervalType(DAY, DAY) or DayTimeIntervalType(DAY) | INTERVAL DAY | INTERVAL ‘100’ DAY |
DayTimeIntervalType(DAY, HOUR) | INTERVAL DAY TO HOUR | INTERVAL ‘100 10’ DAY TO HOUR |
DayTimeIntervalType(DAY, MINUTE) | INTERVAL DAY TO MINUTE | INTERVAL ‘100 10:30’ DAY TO MINUTE |
DayTimeIntervalType(DAY, SECOND) | INTERVAL DAY TO SECOND | INTERVAL ‘100 10:30:40.999999’ DAY TO SECOND |
DayTimeIntervalType(HOUR, HOUR) or DayTimeIntervalType(HOUR) | INTERVAL HOUR | INTERVAL ‘123’ HOUR |
DayTimeIntervalType(HOUR, MINUTE) | INTERVAL HOUR TO MINUTE | INTERVAL ‘123:10’ HOUR TO MINUTE |
DayTimeIntervalType(HOUR, SECOND) | INTERVAL HOUR TO SECOND | INTERVAL ‘123:10:59’ HOUR TO SECOND |
DayTimeIntervalType(MINUTE, MINUTE) or DayTimeIntervalType(MINUTE) | INTERVAL MINUTE | INTERVAL ‘1000’ MINUTE |
DayTimeIntervalType(MINUTE, SECOND) | INTERVAL MINUTE TO SECOND | INTERVAL ‘1000:01.001’ MINUTE TO SECOND |
DayTimeIntervalType(SECOND, SECOND) or DayTimeIntervalType(SECOND) | INTERVAL SECOND | INTERVAL ‘1000.000001’ SECOND |
- Complex 類型
- ArrayType(elementType,containsNull):表示包含elementType類型的元素序列的值。containsNull用于指示ArrayType值中的元素是否可以具有null值。
- MapType(keyType,valueType,valueContainsNull):表示包含一組鍵值對的值。鍵的數據類型由keyType描述,值的數據類型則由valueType描述。對于MapType值,鍵不允許具有null值。valueContainsNull用于指示MapType值的值是否可以具有null值。
- StructType(fields):表示具有由StructFields(fields)序列描述的結構的值。
- StructField(name,dataType,nullable):表示StructType中的字段。字段的名稱由name表示。字段的數據類型由dataType表示。nullable用于指示這些字段的值是否可以具有null值。
Spark SQL的所有數據類型都位于pyspark.sql.types包中。你可以通過以下方式訪問它們
from pyspark.sql.types import *
Data type | Value type in Python | API to access or create a data type |
---|---|---|
ByteType | int或long 注意:數字將在運行時轉換為1字節的有符號整數。請確保數字在-128到127的范圍內。 | ByteType() |
ShortType | int或long 注意:數字將在運行時轉換為2字節的有符號整數。請確保數字在-32768到32767的范圍內。 | ShortType() |
IntegerType | int or long | IntegerType() |
LongType | long 注意:數字將在運行時轉換為8字節的有符號整數。請確保數字在-9223372036854775808到9223372036854775807的范圍內。否則,請將數據轉換為decimal.Decimal并使用DecimalType。 | longtype () |
FloatType | float 注意:數字將在運行時轉換為4字節的單精度浮點數。 | FloatType() |
DoubleType | float | DoubleType() |
DecimalType | decimal.Decimal | DecimalType() |
StringType | string | StringType() |
BinaryType | bytearray | BinaryType() |
BooleanType | bool | BooleanType() |
TimestampType | datetime.datetime | TimestampType() |
TimestampNTZType | datetime.datetime | TimestampNTZType() |
DateType | datetime.date | DateType() |
DayTimeIntervalType | datetime.timedelta | DayTimeIntervalType() |
ArrayType | list, tuple, or array | ArrayType(elementType, [containsNull]) 注意:containsNull默認值為True。 |
MapType | dict | MapType(keyType, valueType, [valueContainsNull]) 注意valueContainsNull默認值為True. |
StructType | list or tuple | StructType(fields) 注意:fields是StructFields的一個序列。另外,不允許有兩個名稱相同的字段。 |
StructField | 該字段的數據類型在Python中的值類型 (例如,對于數據類型為IntegerType的StructField,為Int) | StructField(name, dataType, [nullable]) 注意:nullable默認值為True。 |
二、浮點特殊值
Spark SQL以不區分大小寫的方式支持幾種特殊的浮點值:
- Inf/+Inf/Infinity/+Infinity:正無窮大
- FloatType:相當于Scala Float.PositiveInfinity。
- DoubleType:相當于Scala Double.PositiveInfinity。 - -Inf/-Infinity:負無窮大
- FloatType:相當于Scala Float.NegativeInfinity。
- DoubleType:相當于Scala Double.NegativeInfinity。 - NaN:不是數字
- FloatType:相當于Scala Float.NaN。
- DoubleType:相當于Scala Double.NaN。
三、正負無窮語義
對正無窮大和負無窮大有特殊處理。它們具有以下語義:
- 正無窮大乘以任何正值都會返回正無窮大。
- 負無窮大乘以任何正值返回負無窮大。
- 正無窮大乘以任何負值都會返回負無窮大。
- 負無窮大乘以任何負值都會返回正無窮大。
- 正/負無窮大乘以0返回NaN。
- 正/負無窮大等于它本身。
- 在聚合中,所有正無窮大值都被分組在一起。類似地,所有負無窮大值都被分組在一起。
- 正無窮大和負無窮大被視為join keys中的正常值。
- 正無窮大排序低于NaN,高于任何其他值。
- 負無窮大排序低于任何其他值。
四、NaN語義
在處理與標準浮點語義不完全匹配的float或double類型時,會對非數字(NaN)進行特殊處理。具體來說:
- NaN = NaN返回true。
- 在聚合中,所有NaN值被分組在一起。
- NaN在join keys中被視為正常值。
- NaN值按升序排在最后,比任何其他數值都大。
五、例子
SELECT double('infinity') AS col;
+--------+
| col|
+--------+
|Infinity|
+--------+SELECT float('-inf') AS col;
+---------+
| col|
+---------+
|-Infinity|
+---------+SELECT float('NaN') AS col;
+---+
|col|
+---+
|NaN|
+---+SELECT double('infinity') * 0 AS col;
+---+
|col|
+---+
|NaN|
+---+SELECT double('-infinity') * (-1234567) AS col;
+--------+
| col|
+--------+
|Infinity|
+--------+SELECT double('infinity') < double('NaN') AS col;
+----+
| col|
+----+
|true|
+----+SELECT double('NaN') = double('NaN') AS col;
+----+
| col|
+----+
|true|
+----+SELECT double('inf') = double('infinity') AS col;
+----+
| col|
+----+
|true|
+----+CREATE TABLE test (c1 int, c2 double);
INSERT INTO test VALUES (1, double('infinity'));
INSERT INTO test VALUES (2, double('infinity'));
INSERT INTO test VALUES (3, double('inf'));
INSERT INTO test VALUES (4, double('-inf'));
INSERT INTO test VALUES (5, double('NaN'));
INSERT INTO test VALUES (6, double('NaN'));
INSERT INTO test VALUES (7, double('-infinity'));
SELECT COUNT(*), c2 FROM test GROUP BY c2;
+---------+---------+
| count(1)| c2|
+---------+---------+
| 2| NaN|
| 2|-Infinity|
| 3| Infinity|
+---------+---------+