เหตุใดจึงลบคุณสมบัติเอกลักษณ์ในคอลัมน์ไม่ได้รับการสนับสนุน


11

ฉันได้อ่านแล้วว่าหลังจาก SQL Server 2000 ความสามารถในการ "ยกเลิกการระบุตัวตน" คอลัมน์ข้อมูลประจำตัวจะถูกลบออก และนี่คือ "โดยการออกแบบ" (ไม่ใช่แค่คุณสมบัติที่ขาดหายไป)

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

การหลีกเลี่ยงสิ่งนี้จะทำให้ฉันต้องทำงานเป็นจำนวนมาก (การคัดลอกแถวหลายร้อยล้านแถวไปยังตารางใหม่ในสภาพแวดล้อมที่ไม่หยุดทำงาน)

ดังนั้นฉันคิดว่าฉันจะถาม "ทำไม"

มีอะไรเปลี่ยนแปลงใน SQL Server 2005 และรุ่นที่ใหม่กว่าซึ่งทำให้สิ่งนี้เลว หรือว่ามันแย่เสมอและไม่เพิ่งล็อค?

"แนวปฏิบัติที่ดีที่สุด" (หรือหลักการที่คล้ายกัน) ใดที่จะถูกละเมิดโดยทำให้คอลัมน์ข้อมูลประจำตัวเป็นคอลัมน์ปกติอีกครั้ง

-

อัปเดตเพื่อตอบคำขอ "ทำไมฉันถึงทำแบบนี้":
นี่เป็นบทสรุประดับสูงมาก: ฉันจะเริ่มเพิ่มพาร์ติชันในตารางของฉัน (เพื่อให้ฉันสามารถเก็บถาวร / ล้างข้อมูลเก่า) นั่นคือทั้งหมดที่ง่าย แต่บางครั้งฉันจำเป็นต้องย้ายระเบียนไปยังพาร์ติชันที่แตกต่างกันดังนั้นจึงไม่ถูกลบออก (เมื่อพาร์ติชันเกิดขึ้นสำหรับการเก็บถาวร / ลบ) (ฉันมีการแบ่งคอลัมน์เพิ่มขึ้น 2 เพื่อให้มีพื้นที่เสมอในการย้ายแถวไปยังพาร์ติชันอื่น)

แต่ถ้าคอลัมน์การแบ่งเป็นคอลัมน์ข้อมูลส่วนตัวฉันต้องลบและใส่ค่าใหม่อีกครั้ง (ไม่มีทางที่จะอัพเดทค่าของคอลัมน์ข้อมูลประจำตัว) ซึ่งทำให้เกิดปัญหากับการจำลองแบบ

ดังนั้นฉันต้องการที่จะใช้ลำดับแทนคอลัมน์ข้อมูลประจำตัว แต่สวิตช์นั้นยากมากในฐานข้อมูลขนาดใหญ่

คำตอบ:


22

คำถามของคุณเป็นหลัก:

เหตุใดฉันจึงไม่สามารถทำสิ่งที่มีความเสี่ยงที่ฉันไม่ควรได้รับอนุญาตให้ทำตั้งแต่แรก?

คำตอบสำหรับคำถามนั้นส่วนใหญ่ไม่เกี่ยวข้อง (แม้ว่าคุณจะเห็นความคิดเห็นของ Microsoft บางอย่างในรายการเชื่อมต่อที่ขอใช้ฟังก์ชันนี้: # 294193และ# 252226) เพื่อความสมบูรณ์บทสรุปของฉันคือ: ความสามารถในการลบคุณสมบัติข้อมูลเฉพาะตัวเป็นผลข้างเคียงที่ไม่ได้ตั้งใจของการมีความสามารถในการยุ่งกับตารางระบบในตอนแรก นี่ไม่ได้มีวัตถุประสงค์เพื่อนำไปใช้ในหลาย ๆ วิธีที่มันเป็นบ่อยครั้งที่มีผลกระทบที่เลวร้ายมากและทำให้มันถูกลบออก มันเป็นแฮ็คตารางระบบที่ไม่มีเอกสารสนับสนุน ความสามารถในการเปลี่ยนแปลงข้อมูลในตารางระบบไม่ได้ถูกลบออกเนื่องจาก Microsoft ไม่ต้องการให้คุณแฮ็ควิธีการออกจากคอลัมน์ที่เป็นคอลัมน์ข้อมูลประจำตัว แต่มันถูกลบออกเพราะการเล่นกับตารางระบบมีความเสี่ยงอย่างยิ่ง การลบคุณสมบัติ IDENTITY นั้นไม่ได้เป็นการลบคุณลักษณะเฉพาะเป้าหมายและฉันจะไม่เชื่อมั่นในวิธีการนี้แม้จะย้อนกลับไปในสมัยโบราณเมื่อเป็นไปได้

ที่กล่าวมาเราจะตอบคำถามนี้แทนได้อย่างไร

ฉันจะลบคุณสมบัติตัวตนของคอลัมน์ด้วยเวลาที่น้อยที่สุดหรือไม่มีการหยุดทำงานได้อย่างไร

คุณสามารถทำโดยใช้ALTER TABLE ... SWITCHเทคนิคที่ผมได้เรียนรู้บางอย่างที่ฉันเป็นครั้งแรกจากของเราเองพอลไวท์ในการแก้ไขปัญหาในการเชื่อมต่อ # ตัวอย่างด่วนให้ตารางง่าย ๆ นี้:

CREATE TABLE dbo.Original
(
  ID INT IDENTITY(1,1) PRIMARY KEY,
  name SYSNAME
);
GO

INSERT dbo.Original(name) VALUES(N'foo'),(N'bar');
GO

SELECT * FROM dbo.Original;
GO

ผล:

ID  name
--  ----
1   foo
2   bar

ตอนนี้เรามาสร้างตารางเงาและสลับไปที่มันจากนั้นวางตารางเก่าเปลี่ยนชื่อใหม่จากนั้นกลับสู่กิจกรรมปกติ:

CREATE TABLE dbo.New
(
  ID INT PRIMARY KEY,
  name SYSNAME
);
GO

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
  ALTER TABLE dbo.Original SWITCH TO dbo.New;
  DROP TABLE dbo.Original;
  EXEC sys.sp_rename N'dbo.New', N'Original', 'OBJECT';
COMMIT TRANSACTION;
GO

INSERT dbo.Original(ID,name) VALUES(3,N'splunge');
UPDATE dbo.Original SET ID = 6 WHERE ID = 1;
GO

SELECT * FROM dbo.Original;
GO

ผล:

ID  name
--  -------
2   bar
3   splunge
6   foo

ตอนนี้ทำความสะอาด:

DROP TABLE dbo.Original;

นี่เป็นการดำเนินการเมตาดาต้าเท่านั้นโดยไม่มีการเคลื่อนย้ายข้อมูลและจะบล็อกผู้ใช้รายอื่นในขณะที่กำลังอัปเดตเมตาดาต้าเท่านั้น แต่เป็นที่ยอมรับว่าเป็นตัวอย่างที่ง่ายมาก หากคุณมีคีย์ต่างประเทศหรือใช้คุณสมบัติอื่น ๆ เช่นการจำลองการเปลี่ยนแปลงการเก็บข้อมูลเปลี่ยนการติดตาม ฯลฯ คุณอาจต้องปิดการใช้งานหรือลบบางส่วนก่อนทำการเปลี่ยนแปลงนี้ (ฉันยังไม่ได้ทดสอบชุดค่าผสมทั้งหมด) สำหรับคีย์ต่างประเทศโดยเฉพาะให้ดูเคล็ดลับนี้ซึ่งแสดงวิธีการสร้างสคริปต์เพื่อวางและสร้างข้อ จำกัด คีย์ต่างประเทศทั้งหมด (หรือเลือก) ใหม่

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

โปรดดูสคริปต์นี้จาก Itzik Ben-Gan (ที่มา: บทความโบราณนี้ ) สำหรับวิธีการอื่นในการจัดการกับสิ่งนี้ แต่มีการเคลื่อนย้ายข้อมูลที่เกี่ยวข้องที่นี่ดังนั้นจึงไม่ส่งผ่านข้อกำหนด "ไม่มีหรือหยุดทำงานน้อยที่สุด"


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

ฉันต้องยอมรับด้วยเหตุผลบางอย่างที่ฉันคิดว่า..SWITCH..ใช้ได้เฉพาะกับตารางที่มีพาร์ติชันอย่างน้อยหนึ่งที่กำหนดไว้
RBarryYoung

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