ทศนิยมของเซิร์ฟเวอร์ SQL (9, 0) กับ INT


15

หนึ่งในลูกค้าของเราใช้คอลัมน์ประเภทข้อมูลDECIMAL(18,0)ในฐานข้อมูล SQL Server 2008R2 ของเขา เนื่องจากคอลัมน์เติบโตค่อนข้างช้าเขาจึงเสนอให้เปลี่ยนประเภทข้อมูลเป็นDECIMAL(5,0)พื้นที่เก็บข้อมูลบางส่วน

ตามไลบรารี MSDNพื้นที่เก็บข้อมูลของDECIMAL(5,0)ประเภทข้อมูลนั้นก็เหมือนกับDECIMAL(9,0)ประเภทข้อมูล 5 ไบต์ INTมีขนาดเล็กกว่า 1 ไบต์ แต่สามารถจัดเก็บทุกอย่างในช่วง -2 ^ 31 ถึง 2 ^ 31 แทน -99,999 ถึง 99,999 ซึ่งDECIMAL(5,0)สามารถจัดเก็บได้ แม้แต่ใหญ่ที่สุดDECIMALซึ่งพอดีกับ 5 ไบต์ ( DECIMAL(9,0)) สามารถเก็บเฉพาะจำนวนเต็มในช่วง -999,999,999 ถึง 999,999,999 (ซึ่งน้อยกว่าครึ่งหนึ่งของช่วงที่INTเสนอใน 4 ไบต์)

ฉันนึกถึง "ผลประโยชน์" สองอย่างของการใช้DECIMALเกินINT:

  • ความสามารถในการเพิ่มสเกลในภายหลังโดยไม่ต้องใช้พื้นที่เก็บข้อมูลเพิ่มเติม
  • ความสามารถในการขยายความแม่นยำสูงถึง 38 หลักโดยไม่ต้องเปลี่ยนประเภทข้อมูล

แต่นี่ไม่ใช่ประโยชน์ที่แท้จริงในความคิดของฉัน:

  • การเพิ่มสเกลให้กับจำนวนเต็มนั้นเหมาะสมในบางกรณีเท่านั้น (ในกรณีส่วนใหญ่ที่สเกลนั้นสร้างความแตกต่างก็สามารถเพิ่มได้ล่วงหน้า)
  • SQL Server เห็นการรวมกันของความแม่นยำ / มาตราส่วนเป็นชนิดข้อมูลที่แตกต่างกันดังนั้นประเภทข้อมูลไม่ได้ถูกทิ้งไว้ตามลำพังเมื่อเพิ่มความแม่นยำหรือระดับ

สิ่งนี้ทำให้ฉันประหลาดใจ: อะไรคือประโยชน์เพิ่มเติมของDECIMAL(5,0)ประเภทข้อมูลสำหรับจำนวนเต็ม?


1
หนึ่งประโยชน์สามารถเป็นขีด จำกัด ห้าหลัก แต่ฉันสงสัยว่าคุณมีพื้นที่เก็บข้อมูลมากน้อยเพียงใดด้วยการเปลี่ยนแปลง
dezso

3
IMO หากคุณต้องการตรวจสอบให้แน่ใจว่าค่าคอลัมน์อยู่ในช่วงให้ใช้ข้อ จำกัด การตรวจสอบ ฉันคิดว่าสิ่งเดียวที่ควรพิจารณาคือหากมีความเป็นไปได้ที่คอลัมน์นี้จะต้องการค่าเศษส่วนในอนาคต
Jon Seigel

3
หากพวกเขากังวลเกี่ยวกับพื้นที่เก็บข้อมูลพวกเขาจะเหมาะสมกว่าเมื่อใช้การบีบอัดมากกว่านี้ ไม่มีประโยชน์ที่เป็นรูปธรรมในการใช้ทศนิยม (x, 0) แทนที่จะเป็น int / bigint
Robert L Davis

7
ความแตกต่างระหว่างdecimal(x,0)และประเภทจำนวนเต็มอื่นแสดงให้เห็นว่าตัวเองในการแบ่งเลขคณิต ถ้าคุณหาร int ด้วย int คุณจะได้ int ถ้าคุณหารทศนิยม (x, 0) ด้วย int คุณจะได้ทศนิยม (x + 6,6)
Andriy M

@AndriyM ฉันคิดว่านี่เป็นประโยชน์ที่ยิ่งใหญ่ที่สุด ใส่คำตอบลงในคำตอบแทนความคิดเห็นและฉันจะทำเครื่องหมายว่าเป็นคำตอบ
vstrien

คำตอบ:


8

ฉันยอมรับว่าไม่มีผลประโยชน์ที่แท้จริงในแง่ของพื้นที่เก็บข้อมูลตราบใดที่คุณเปรียบเทียบ DECIMAL (9, 0) กับ INT หรือ DECIMAL (18, 0) กับ BIGINT (ภายในหนึ่งไบต์)

ในแง่ของการประมวลผลเช่น @Andriy กล่าวว่า DECIMAL จะแบ่งออกเป็นประเภทที่ไม่สูญเสียส่วนที่เป็นเศษส่วนหากเป็นเรื่องสำคัญสำหรับคุณ

ในทางกลับกันการทำงานกับชนิด INT ดั้งเดิมนั้นเร็วกว่ามากจากจุดยืนเชิงตัวเลขหากคุณทำการ SUM () จำนวนมากหรือการเปรียบเทียบ (เช่นการค้นหาค่า) เนื่องจาก CPU ถูกวางตำแหน่งอย่างมีประสิทธิภาพมากขึ้น การเปรียบเทียบ int เป็นสองแอสเซมบลี opcodes (MOV, CMP) แต่การเปรียบเทียบทศนิยมใด ๆ จะมากขึ้นอีกมากมาย


คำตอบของคุณเหมาะสม แต่โปรเซสเซอร์ไม่มีความรู้ด้านประเภทข้อมูล ดังนั้นประเภทข้อมูลหนึ่งของ 4 ไบต์เปรียบเทียบเร็วเท่าประเภทข้อมูลอื่นของ 4 ไบต์ คุณสามารถแสดง (ด้วยการทดสอบประสิทธิภาพที่ทำซ้ำได้) ที่มีการใช้งานDECIMAL(9, 0)แทนการใช้งานINTหรือไม่?
vstrien

2
ฉันคิดว่าฉันทำได้ แต่ฉันยอมรับว่าการทดสอบของฉันไม่สามารถสรุปได้ บางที SQL กำลังทำการปรับให้เหมาะสมเพื่อลดปัญหาให้เป็นเลขจำนวนเต็ม testbed ของฉัน: `- เปรียบเทียบ SET @StartTime = SYSDATETIME () ในขณะที่ (@CounterINT <@SizeINT) SET @CounterINT = @CounterINT + @ PRINT + 1 PRINT 'INT เอา' + แปลง (VARCHAR (20), DATEDIFF (มิลลิวินาที, @StartTime) , SYSDATETIME ())) + 'มิลลิวินาที' - ทศนิยมชุด @StartTime = SYSDATETIME () ในขณะที่ (@CounterDEC <@SizeDEC) SET @CounterDEC = @CounterDEC + 1 พิมพ์ 'DEC เอา' + CONVERT (VARCHAR (20), DATEDIFF (มิลลิวินาที, @StartTime, SYSDATETIME ())) + 'มิลลิวินาที' '
Chris Chubb

ฉันคิดว่า SQL Server ปรับสิ่งที่มีอย่างแท้จริง แม้ว่าการเพิ่มประสิทธิภาพDECIMALยังคงใช้เวลานานกว่าปกติ (อย่างน้อยในระบบการพัฒนาของฉัน) ในการทดสอบ 10 ครั้งประมาณ 51 ms ธันวาคมเทียบกับ 46 ms INT
vstrien

2

ดูเหมือนว่าจะไม่มีประโยชน์ในแง่ของพื้นที่เก็บข้อมูล

หากคุณลูกค้ามีความกังวลว่าค่าคุณจะมีขนาดใหญ่กว่า 2 ^ 32-1 (สูงสุดจำนวนเต็มค่าบวกสามารถเก็บ) แล้วคุณควรพิจารณาที่จะย้ายไปbigint - มีเป็น 64 บิต ( 8 ไบต์)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.