DOAG: Beitrag Trivadis GmbH, Peter Jensch Juni 2004 Betrifft Primary-Key-Constraints und Reihenfolge von Tabellen-Attributen Art der Info Technische Background Info Quelle Aus unserer Schulungs- und Beratungstätigkeit Einleitung Applikationen leben von Veränderungen und Erweiterungen. Dies gilt selbstverständlich auch für Applikationen im Oracle-Umfeld. Durch notwendige Erweiterungen kommt es bei der nachfolgenden Erstellung von Datenbank-Constraints gelegentlich zu kleinen Interpretationsproblemen. Werden später erstellte Attribute für die Erstellung der Primary-Key-Constraints verwendet, kann ggf. nicht mehr das erste oder die ersten Attribute der Basis-Tabelle verwendet werden. Eine mühsame Korrektur der Tabellen-Definition ist die Folge. Eine Bereinigung der Struktur-Definition der Tabelle sollte aber in jedem Fall durchgeführt werden, da bereits mit dem SQL*Plus-Tool unter Verwendung des DESCRIBE-Kommandos der Entwickler leicht in die Irre geführt werden kann. Sicherlich wird eine genaue Analyse der Constraints schnell erkennen lassen, dass das DESCRIBE-Kommando nicht oder nur eingeschränkt für eine Constraint-Interpretation verwendet werden kann. Beispiel: SQL> desc dept_sekt Name -------------------------------------DEPTNO DNAME LOC DEPT_SECTION Null? Type -------- -------------------------NOT NULL NUMBER(2) VARCHAR2(14) VARCHAR2(13) NOT NULL VARCHAR2(1) Die Tabelle dept_sekt wurde mit Hilfe des ALTER TABLE Befehls um das Attribut dept_section erweitert. Wird ein neues Attribut einer Tabelle hinzugefügt, so wird dieses als letztes der Tabelle in der Attributliste angehängt. Unabhängig davon wurde dieses Attribut in unserem Beispiel in die Primary-Key-Constraint-Definition aufgenommen. Üblicherweise geht man davon aus, dass das erste Attribut bzw. die ersten Attribute für die Definition des Primary-Key-Constraint verwendet werden. Mit der Definition des PKConstraints wird automatisch ein NOT NULL Constraint auf die betroffenen Attribute erstellt. Diese NOT NULL-Constraints, insbesondere am Tabellen-Anfang, führen oft zum Schluss, diese Attribute gehören zur PK-Constraint-Definition. Dies ist nicht natürlich automatisch richtig! Bei einer genaueren Analyse des Beispiels unter Verwendung der Data-Dictionary-Views user_constraints und user_cons_columns erkennt man schnell, dass in diesem Fall der Primary-Key aus den Attributen deptno und dept_sektion aufgebaut ist: SQL> SELECT constraint_name, constraint_type, table_name 2 FROM user_constraints 3 WHERE table_name = 'DEPT_SEKT'; CONSTRAINT_NAME C TABLE_NAME ------------------------------ - -----------------------------PK_DEPT_SEKT P DEPT_SEKT SQL> col table_name format a15 SQL> col column_name format a15 SQL> SELECT constraint_name, table_name, column_name, position 2 FROM user_cons_columns 3 WHERE table_name = 'DEPT_SEKT'; CONSTRAINT_NAME -----------------------------PK_DEPT_SEKT PK_DEPT_SEKT TABLE_NAME --------------DEPT_SEKT DEPT_SEKT COLUMN_NAME POSITION --------------- ---------DEPTNO 1 DEPT_SEKTION 2 Die NOT NULL-Definition aus dem DESCRIBE-Kommando wird automatisch über den Primary-Constraint erstellt und kann aus der View user_tab_columns im Attribut NULLABLE eingesehen werden: SQL> SELECT table_name, column_name, nullable 2 FROM user_tab_columns 3 WHERE table_name = 'DEPT_SEKT'; TABLE_NAME --------------DEPT_SEKT DEPT_SEKT DEPT_SEKT DEPT_SEKT COLUMN_NAME --------------DEPTNO DNAME LOC DEPT_SEKTION N N Y Y N Eine weitere Möglichkeit die Informationen aus der Datenbank zu lesen: SQL> col tablename format a15 SQL> col constraint_name format a15 SQL> SELECT c.table_name 2 , c.constraint_name 3 , cc.column_name 4 , tc.column_id 5 , cc.position 6 FROM user_constraints c 7 , user_cons_columns cc 8 , user_tab_columns tc Tablename Constraint_Name Column_Name Tab_Position Con_Position 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 WHERE AND AND AND AND tc.table_name = c.table_name c.constraint_name = cc.constraint_name tc.column_name = cc.column_name c.constraint_type = 'P' c.table_name IN (SELECT c1.table_name FROM user_constraints c1 , user_cons_columns cc1 , user_tab_columns tc1 WHERE tc1.table_name = AND c1.constraint_name = AND tc1.column_name = AND cc1.position != AND c1.constraint_type = ORDER BY c.owner, c.table_name, cc.position c1.table_name cc1.constraint_name cc1.column_name tc1.column_id 'P') / TABLENAME --------------DEPT_SEKT DEPT_SEKT CONSTRAINT_NAME --------------PK_DEPT_SEKT PK_DEPT_SEKT COLUMN_NAME TAB_POSITION CON_POSITION --------------- ------------ -----------DEPTNO 1 1 DEPT_SEKTION 4 2 Jetzt erkennt man schnell, dass das zweite Constraint-Attribut das 4-te Attribut in der Tabellen-Definition ist. Für eine Reorganisation bietet sich ein CREATE TABLE AS SELECT (CTAS) an. Die Attribute werden in neuer Reihenfolge in der Select-Liste angegeben. Die „alte“ Tabelle muss gelöscht und die neue Tabelle umbenannt werden. Bei dieser Methode werden die Constraints der referenziellen Integrität, Trigger, Grants usw. nicht kopiert und müssen von Hand neu erstellt werden. Für die optimale Erstellung von Tabellen werden häufig folgende Richtlinien zu Grunde gelegt: - Primary-Key-Constraint-Attribute sind die ersten Attribute einer Tabelle NOT NULL Attribute sollten so häufig wie möglich gesetzt werden. Diese Attribute sind die ersten Spalten einer Tabelle Je häufiger ein Attribut einer Tabelle verwendet wird, umso weiter „vorne“ in der Attributliste sollte dieses Attribut in der Tabellendefinition verwendet werden Darüberhinaus kann eine Strukturanpassung der Tabellen, die einen Neuaufbau notwendig machen, den Blockfüllungsgrad und die Performance verbessern. Ein nicht zu verachtender Nebeneffekt! Das folgende Beispiel zeigt den Neuaufbau einer Tabelle mit dem „Create Table As Select“ – Befehl. SQL> create table dept_sekt_neu 2 as select deptno, dept_sektion, dname, loc 3 from dept_sekt 4 order by deptno; Table created. SQL> alter table dept_sekt_neu add (constraint pk_dept_sekt_neu 2 primary key ( deptno, dept_sektion ) validate; Table altered. SQL> desc dept_sekt_neu Name -------------------------------------DEPTNO DEPT_SEKTION DNAME LOC Null? -------NOT NULL NOT NULL Type -------------------------NUMBER(2) VARCHAR2(1) VARCHAR2(14) VARCHAR2(13) Weitere Möglichkeiten, wie beispielsweise eine Online-Reorganisation, ergeben sich ab der Oracle-Version 9i unter Verwendung des Standard-Package DBMS_REDEFINITION oder der Verwendung des Trivadis Reorganisation Tools TabReorg. Eine jederzeit geordnete und interessante Referenz zu diesem, oder auch zu anderen Themen, wie Online-Reorganisation, New Features, Tipps und Tricks bietet die Trivadis Webseite. Oder Sie besuchen einen unserer Kurse ☺ Peter Jensch Trivadis GmbH Peter Jensch Max – Lang – Str. 59 70771 Leinfelden - Echterdingen Internet: http://www.trivadis.com Mail: [email protected] Tel: +49 +711 90 36 32 30 Fax: +49 +711 90 36 32 59