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|
+---------+---------+