Amazon Redshiftのカーソル制限/トランザクション/データ型など気になった点

# はじめに
Amazon Redshiftについて、自分が気になった部分を書き出してみました。

# カーソルの制限
DECLAREの説明にあるとおり、カーソルに制限があります。

https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/declare.html

> * 1 つのセッションで、同時に開くことができるカーソルは 1 つのみです。

1セッション1カーソルです。
ODBCを使って複数カーソルを使って処理しているアプリケーションは、接続先がRedshiftの場合だけカーソル操作を直列になるようにする必要があるようです。

> * すべてのカーソルの累積結果セットの最大サイズは、クラスターノードタイプに基づいて制限されます。より大きな結果セットが必要な場合は、XL または 8XL ノード構成にサイズ変更できます。
>   詳細については、「カーソルの制約」を参照してください。

1セッション1カーソルなので、「すべてのカーソル」というのは「すべての**セッション**のカーソル」ですね。

# トランザクション分離
「SERIALIZABLE」のみです。
直列化可能な分離ができない場合（同時実行の場合と同じ結果を生成するオペレーションを連続して実行できる順序がない場合）には「ERROR:1023」エラーとなるとのことです。
結局クエリのみのトランザクションと更新系のトランザクションの衝突では双方待機は発生しない、ということですよね？
「READ ONLY」についての詳しい説明はありませんが、クエリのみの場合は指定したほうがよさそうには思います。

https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_BEGIN.html

>4つのトランザクション分離レベルのいずれも使用できますが、Amazon Redshift ではすべての分離レベルを直列化可能として処理します。

https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/c_serial_isolation.html

>各トランザクションの SELECT ステートメントの結果は、もう一方の INSERT ステートメントの影響を受ける可能性があります。つまり、次のステートメントを任意の順序で連続して実行するとします。いずれの場合でも、結果として、トランザクションが同時に実行された場合よりも、SELECT ステートメントで 1 行多く返ります。同時実行の場合と同じ結果を生成するオペレーションを連続して実行できる順序はありません。そのため、最後に実行されるオペレーションは、直列化可能な分離エラーになります。

# 文字型

* CHAR型にはマルチバイト文字は格納できません。VARCHAR型を使う必要があります。
* UTF-8で格納されます。
* 照合順序はUTF-8のバイナリ順です。
* CHAR(N)/VARCHAR(N)のNにはバイト長(文字数ではなく)を指定します。
* NCHAR型/NVARCHAR型はCHAR型/VARCHAR型のシノニムで、NCHAR(N)/NVARCHAR(N)のNにもバイト長を指定します。
* 一方でSUBSTRING関数の先頭位置、長さは文字単位で指定します。
* 後方空白は比較やグループ化では無視されます。

https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_Character_types.html

https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_SUBSTRING.html

https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/c_collation_sequences.html

# DECIMAL 型または NUMERIC 型

* DECIMAL(38,38)は定義できない。scaleは37まで。
* DECIMAL(19,*)は推奨されない。
* 内部形式は19桁以下は8バイト整数(64ビット値)。20桁以上は16バイト整数(128ビット値)。

https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_Numeric_types201.html#r_Numeric_types201-decimal-or-numeric-type
>precision
>デフォルトの精度は 18 です。最大精度は 38 です。
>scale
>列の仕様では、スケール値は精度値以下である必要があります。指定がなければ、デフォルトのスケールは 0 です。最大スケールは 37 です。

>注記
>DECIMAL(19,0) 列に挿入できる最大の正の値は、9223372036854775807 (263 -1) です。
>：
>Amazon Redshift では、この精度が必要でない限り、19 桁の精度で DECIMAL 値を定義しないことをお勧めします。

https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_numeric_computations201.html
>DECIMAL の計算結果の精度とスケール
>(これらの計算に関係なく、結果の最大精度は 38、**結果の最大スケールは 38 です**)。

>オーバーフロー条件
>すべての数値計算についてオーバーフローが調べられます。精度が 19 以下の DECIMAL データは 64 ビットの整数として格納されます。精度が 19 を上回る DECIMAL データは 128 ビットの整数として格納されます。すべての DECIMAL 値の最大精度は 38 であり、**最大スケールは 37 です**。値がこれらの制限を超えるとオーバーフローエラーが発生します。このルールは中間結果セットと最終結果セットの両方に適用されます。

オーバーフロー条件の記述から「結果の最大スケールは 37 です」の誤りのような気がします。

>除算演算に関する注意事項
>精度とスケールが計算されると、スケール制限 100 が適用されます。算出された結果スケールが 100 より大きい場合、除算結果は次のようにスケーリングされます。
>精度 = precision - (scale - max_scale)
>スケール = max_scale
>算出された精度が最大精度 (38) より高い場合、精度は 38 に引き下げられ、スケールは max(38 + scale - precision), min(4, 100)) で計算された結果となります。

中間結果セットと最終結果セットは精度38桁、スケール37桁を超えないはず。
「スケール制限 100 」「max_scale」「max(38 + scale - precision), min(4, 100))」が不明。

# 大文字と小文字を区別する識別子
大文字小文字を区別したい場合は構成パラメタ変更が必要です。
SETコマンドでセッション内で設定することもできます。

https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_names.html
>大文字と小文字を区別する識別子を使用するには、構成 enable_case_sensitive_identifier を true に設定します。

# ORDER BY
NULLは昇順では最後、降順では先頭に位置します。

https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_ORDER_BY_clause.html

>NULLS FIRST | NULLS LAST
>NULL 値を NULL 以外の値より先に順序付けするか、NULL 以外の値の後に順序付けするかを指定するオプション。デフォルトでは、NULL 値は昇順ではソートされて最後にランク付けされ、降順ではソートされて最初にランク付けされます。