ปัญหา
หมายเหตุ: ผมหมายถึงลำดับคณิตศาสตร์ไม่ใช่กลไกลำดับของ PostgreSQL
ฉันมีตารางที่แสดงลำดับของจำนวนเต็ม ความหมายคือ:
CREATE TABLE sequences
(
id serial NOT NULL,
title character varying(255) NOT NULL,
date date NOT NULL,
sequence integer[] NOT NULL,
CONSTRAINT "PRIM_KEY_SEQUENCES" PRIMARY KEY (id)
);
เป้าหมายของฉันคือการหาแถวโดยใช้ลำดับที่กำหนด กล่าวคือแถวที่sequence
เขตข้อมูลเป็นลำดับที่มีการเรียงลำดับที่กำหนด (ในกรณีของฉันลำดับจะเรียงตามลำดับ)
ตัวอย่าง
สมมติว่าตารางมีข้อมูลต่อไปนี้:
+----+-------+------------+-------------------------------+
| id | title | date | sequence |
+----+-------+------------+-------------------------------+
| 1 | BG703 | 2004-12-24 | {1,3,17,25,377,424,242,1234} |
| 2 | BG256 | 2005-05-11 | {5,7,12,742,225,547,2142,223} |
| 3 | BD404 | 2004-10-13 | {3,4,12,5698,526} |
| 4 | BK956 | 2004-08-17 | {12,4,3,17,25,377,456,25} |
+----+-------+------------+-------------------------------+
ดังนั้นหากการเรียงลำดับที่กำหนดคือ{12, 742, 225, 547}
ฉันต้องการหาแถวที่ 2
ในทำนองเดียวกันถ้าการเรียงลำดับที่กำหนดคือ{3, 17, 25, 377}
ฉันต้องการหาแถว 1 และ 4 แถว
ในที่สุดหากการเรียงลำดับที่กำหนดคือ{12, 4, 3, 25, 377}
จากนั้นจะไม่มีการส่งคืนแถว
สืบสวน
อันดับแรกฉันไม่แน่ใจว่าการเรียงลำดับด้วยอาร์เรย์ชนิดข้อมูลนั้นฉลาดหรือไม่ แม้ว่ามันจะดูเหมาะสมกับสถานการณ์ก็ตาม ฉันกลัวว่ามันจะทำให้การจัดการที่ซับซ้อนมากขึ้น บางทีอาจเป็นการดีกว่าที่จะแสดงลำดับต่างกันโดยใช้รูปแบบความสัมพันธ์กับตารางอื่น
ในทำนองเดียวกันฉันคิดว่าจะขยายลำดับโดยใช้unnest
ฟังก์ชันอาร์เรย์แล้วเพิ่มเกณฑ์การค้นหาของฉัน อย่างไรก็ตามจำนวนคำศัพท์ในลำดับนั้นเป็นตัวแปรฉันไม่เห็นวิธีการทำเช่นนั้น
ฉันรู้ว่ามันเป็นไปได้ที่จะตัดลำดับของฉันตามลำดับโดยใช้subarray
ฟังก์ชั่นของโมดูลintarrayแต่ฉันไม่เห็นว่ามันมีประโยชน์กับฉันอย่างไรสำหรับการค้นหาของฉัน
ข้อ จำกัด
แม้ว่าในขณะนี้แบบจำลองของฉันยังคงได้รับการพัฒนาตารางก็มีจุดประสงค์ที่จะประกอบไปด้วยหลายลำดับระหว่าง 50,000 ถึง 300,000 แถว ดังนั้นฉันมีข้อ จำกัด ด้านประสิทธิภาพที่แข็งแกร่ง
ในตัวอย่างของฉันฉันใช้จำนวนเต็มค่อนข้างน้อย bigint
ในทางปฏิบัติมันเป็นไปได้ว่าจำนวนเต็มเหล่านี้กลายเป็นมีขนาดใหญ่มากขึ้นไปล้น ในสถานการณ์เช่นนี้ฉันคิดว่าวิธีที่ดีที่สุดคือการจัดเก็บตัวเลขเป็นสตริง (เนื่องจากไม่จำเป็นต้องดำเนินการตามลำดับของการดำเนินการทางคณิตศาสตร์เหล่านี้) อย่างไรก็ตามการเลือกใช้โซลูชันนี้ทำให้ไม่สามารถใช้โมดูลintarray ที่กล่าวถึงข้างต้น
numeric
และไม่ใช่สตริง ( text
ตัวอย่าง)? ฉันไม่จำเป็นต้องดำเนินการทางคณิตศาสตร์กับลำดับของฉัน
text
และป้องกันไม่ให้คุณจัดเก็บข้อมูลที่ไม่ใช่ตัวเลขปลอม ขึ้นอยู่กับว่าหากคุณทำ I / O เพียงอย่างเดียวคุณอาจต้องการข้อความเพื่อลดการประมวลผล I / O
SELECT ARRAY[12, 4, 3, 17, 25, 377, 456, 25] @> ARRAY[12, 4, 3, 25, 377];
จะคืนค่าจริงเนื่องจากออเดอร์นี้ไม่ได้รับการพิจารณา
bigint
คุณควรใช้numeric
เป็นประเภทในการจัดเก็บพวกเขา มันช้ากว่ามากและใช้พื้นที่มากขึ้น