7

14 バイトのデータをbytea含む列があります。14 バイトの最後の 3 バイトには、データの CRC コードが含まれています。CRC を単一の整数として抽出し、新しい列に格納したいと考えています。

どうすればこれを行うことができますか?

明確にするために、Javaでそれを行う1つの方法を次に示します。

int crc = ((rawData[len - 3] & 0xff) << 16 |
            (rawData[len - 2] & 0xff) << 8 |
            (rawData[len - 1] & 0xff)) & 0xffffff;

ビットシフトのない解決策、つまり4バイトを受け入れて整数に変換するメソッドのようなものを見つけたいと思っています。

4

4 に答える 4

15

もう 1 つの方法は、hex表現の最後の 6 文字を抽出し、先頭に を追加しxて直接キャストすることです。

db=# SELECT ('x' || right('\x00000000000001'::bytea::text, 6))::bit(24)::int;
 int4
------
    1

get_byte().. これはルートよりも少し短いですが、PostgreSQLの文書化されていない機能でもあります。ただし、ここでトム・レーンを引用します。

これは、ビット型入力コンバーターの文書化されていない動作に依存していますが、それが壊れると予想する理由はありません。おそらくより大きな問題は、PG >= 8.3 が必要なことです。これより前にビット キャストするテキストがなかったからです。

この関連する回答の詳細:

これは、バージョン 9.0 以降のデフォルトであるの設定bytea_outputがであることを前提としています。hex確かに、セッション用にテスト/設定できます。

SET bytea_output = 'hex';

詳細はこちら:

パフォーマンス

10,000 行のテーブルでテスト (ベスト 10) を実行しました。get_byte()Postgres 9.1 では、実際には少し高速です。

CREATE TEMP TABLE t (a bytea);
INSERT INTO t
SELECT (12345670000000 + generate_series(1,10000))::text::bytea;

ビットシフトは、乗算/加算とほぼ同じくらい高速です。

SELECT 
 ('x' || right(a::text, 6))::bit(24)::int                           -- 34.9 ms
,(get_byte(a, 11) << 16) + (get_byte(a, 12) << 8) + get_byte(a, 13) -- 27.0 ms
,(get_byte(a, 11) << 16) | (get_byte(a, 12) << 8) | get_byte(a, 13) -- 27.1 ms
, get_byte(a, 11) * 65536 + get_byte(a, 12) * 256 + get_byte(a, 13) -- 27.1 ms
FROM t
于 2013-06-20T12:50:53.290 に答える
5
select get_byte(b, 11) * 65536 + get_byte(b, 12) * 256 + get_byte(b, 13)
from (values ('12345678901234'::bytea)) s(b);
 ?column? 
----------
  3289908
于 2013-06-20T12:11:34.223 に答える
4

バイトごとの操作を行う場合、ビット シフトはおそらく乗算よりもはるかに効率的です。

Clodoaldo Neto の回答に基づいて、次のように言います。

select (get_byte(arm_data, 11) << 16) |
       (get_byte(arm_data, 12) << 8) |
       (get_byte(arm_data, 13))
            from adsb_raw_message;

誰もが同意しますか?

于 2013-06-20T14:29:30.913 に答える
0

CRC を単一の整数として別の列に格納する場合は、挿入時または更新時に変換することをお勧めします。の値とともに永続化しますbytea

アプリケーション/ビジネス層でこれを行うか、挿入/更新トリガーを使用して CRC 列を埋めることができます。

于 2013-06-20T09:18:10.610 に答える