Primary-Key-Constraints und Reihenfolge von Tabellen

Größe: px
Ab Seite anzeigen:

Download "Primary-Key-Constraints und Reihenfolge von Tabellen"

Transkript

1 Primary-Key-Constraints und Reihenfolge von Tabellen Autor: Peter Jensch, Trivadis GmbH DOAGNews Q3_2004 Dieses Werk ist urheberrechtlich geschützt. Die dadurch begründeten Rechte, insbesondere die der Übersetzung, des Nachdrucks, des Vortrags, der Entnahme von Abbildungen und Tabellen, der Funksendung, der Mikroverfilmung oder der Vervielfältigung auf anderen Wegen und der Speicherung in Datenverarbeitungsanlagen, bleiben, bei auch nur auszugsweiser Verwertung, vorbehalten. Eine Vervielfältigung dieses Werkes oder von Teilen dieses Werkes ist auch im Einzelfall nur in den Grenzen der gesetzlichen Bestimmungen des Urheberrechtes der Bundesrepublik Deutschland vom 9. September 1965 in der jeweils geltenden Fassung zulässig. Sie ist grundsätzlich vergütungspflichtig. Zuwider-handlungen unterliegen den Straf-bestimmungen des Urheberrechtsgesetzes.

2 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 Null? Type DEPTNO NOT NULL NUMBER(2) DNAME VARCHAR2(14) LOC VARCHAR2(13) DEPT_SECTION 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 PK-Constraints 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:

3 SQL> SELECT constraint_name, constraint_type, table_name 2 FROM user_constraints 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 CONSTRAINT_NAME TABLE_NAME COLUMN_NAME POSITION PK_DEPT_SEKT DEPT_SEKT DEPTNO 1 PK_DEPT_SEKT DEPT_SEKT 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 TABLE_NAME COLUMN_NAME N DEPT_SEKT DEPTNO N DEPT_SEKT DNAME Y DEPT_SEKT LOC Y DEPT_SEKT DEPT_SEKTION 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 Tablename 2, c.constraint_name Constraint_Name 3, cc.column_name Column_Name 4, tc.column_id Tab_Position 5, cc.position Con_Position 6 FROM user_constraints c

4 7, user_cons_columns cc 8, user_tab_columns tc 9 WHERE tc.table_name = c.table_name 10 AND c.constraint_name = cc.constraint_name 11 AND tc.column_name = cc.column_name 12 AND c.constraint_type = 'P' 13 AND c.table_name IN (SELECT c1.table_name 14 FROM user_constraints c1 15, user_cons_columns cc1 16, user_tab_columns tc1 17 WHERE tc1.table_name = c1.table_name 18 AND c1.constraint_name = cc1.constraint_name 19 AND tc1.column_name = cc1.column_name 20 AND cc1.position!= tc1.column_id 21 AND c1.constraint_type = 'P') 22 ORDER BY c.owner, c.table_name, cc.position 23 / TABLENAME CONSTRAINT_NAME COLUMN_NAME TAB_POSITION CON_POSITION DEPT_SEKT PK_DEPT_SEKT DEPTNO 1 1 DEPT_SEKT PK_DEPT_SEKT 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.

5 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 Null? Type DEPTNO NOT NULL NUMBER(2) DEPT_SEKTION NOT NULL VARCHAR2(1) DNAME VARCHAR2(14) LOC 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. Kontakt: Peter Jensch Trivadis GmbH