と の 2 つのテーブルがcategory(cat_id type int,cat_name)
ありbooks(book_id type int,cat_id)
ます。ユーザーに書籍を割り当てると、ユーザーはbook code
. 12 文字の英数字を含むこの書籍コードを作成したいのですが、そのコードはcat_id
およびbook_id
. cat_id
また、コードをデコードしてとを取得できるはずbook_id
です。何か案が?。
3 に答える
HEX を使用する簡単な方法もありますが、書籍に使用する桁数とカテゴリに使用する桁数を決定する必要があります。
たとえば、書籍には 8、カテゴリには 4 を使用することをお勧めします。16 進数を使用すると、最大レコードは FFFFFFFF FFFF になり、本 (最大 4294967295 本) と 65535 カテゴリの unsigned int をすべて使い切ることができます。
実際にLPAD(HEX(book_id), 8, '0')
は、最初の 8 桁とLPAD(HEX(cat_id), 4, '0')
最後の 4 桁です。
あなたが望む本のコードはSELECT CONCAT(LPAD(HEX(book_id), 8, '0'),LPAD(HEX(cat_id), 4, '0')) FROM books
元に戻すには:
SELECT UNHEX(substr(code,1,8)) as book_id, UNHEX(substr(code,9,4)) as cat_id FROM bookcode WHERE id=1
書籍コードでより多くのデータ セットが必要な場合は、両方のアイテムに対して base36 または base62 (大文字と小文字を区別する) エンコーディングを試すことができます。このようなエンコーディングには、ユーザー プロシージャの独自のコードが必要です。
よし、どうぞ…
これは、最大の符号付き整数型を処理できます。生成される文字数は 12 文字以下です。
$firstId = "2147483646";
$secondId = "2147483646";
$firstBinary = str_pad(base_convert($firstId, 10, 2), 31, "0", STR_PAD_LEFT);
$secondBinary = str_pad(base_convert($secondId, 10, 2), 31, "0", STR_PAD_LEFT);
$finalBase36 = str_pad(base_convert($firstBinary.$secondBinary, 2, 36), 12, "0", STR_PAD_LEFT);
var_dump($finalBase36);
更新:申し訳ありませんが、私は間違いを犯しました..これは、更新されたコードでトリックを行う必要があります.
int
タイプが 32 ビットの符号なし整数であると仮定します。2int
を組み合わせると、2^64 個の一意の値があり、これは約 1.844e19 です。
小文字または大文字の英語のアルファベットと数字のみを使用すると、36^12 = 4.738e18 の異なる値があり、2 つのキーから書籍コードへの 1 対 1 のマッピングを作成するには不十分です。
書籍コードの文字セットにさらに 5 文字を追加すると、41^12 = 2.256e19 の異なる値が存在し、1 対 1 のマッピングを作成するにはこれで十分です。
ただし、変換には除算と乗算が含まれるため、ブック コードからキーに戻すときに整数オーバーフローが発生する可能性があります。
可能であれば、文字セットを 64 文字に拡張することをお勧めします: 小文字/大文字の 26 * 2 英語のアルファベット、10 桁、および 2 つの特殊文字 (おそらく_
または-
)、ビットシフトで遊ぶことができます。整数オーバーフロー。未使用のビットについては、2 つのキーによってシードされるランダム データで埋めることができます。逆の構成では、ランダム ビットの (固定) 位置が無視されます。