{"id":129,"date":"2011-06-25T16:34:00","date_gmt":"2011-06-25T14:34:00","guid":{"rendered":"http:\/\/www.flip-design.de\/?p=129"},"modified":"2011-06-26T21:17:28","modified_gmt":"2011-06-26T19:17:28","slug":"patritionierung-von-bestehenden-tabellen","status":"publish","type":"post","link":"https:\/\/www.flip-design.de\/?p=129","title":{"rendered":"Partitionierung von bestehenden Tabellen"},"content":{"rendered":"<p><a href=\"http:\/\/www.flip-design.de\/wp-content\/uploads\/2011\/04\/SQLServerPartitionierung-e1301848983676.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignleft size-full wp-image-48\" title=\"SQLServerPartitionierung\" src=\"http:\/\/www.flip-design.de\/wp-content\/uploads\/2011\/04\/SQLServerPartitionierung-e1301848983676.png\" alt=\"\" width=\"160\" height=\"93\" \/><\/a>In dem Artikel <a href=\"http:\/\/www.flip-design.de\/?p=47\">Partitionierung von SQL Server Tabellen<\/a> habe ich bereits beschrieben, wie man die Partionierung auf eine neue Tabelle anwendet. In der Praxis f\u00fchrt man solche Technologien doch eher an bestehenden Tabellen ein, wenn man merkt, das die Tabelle doch gr\u00f6\u00dfer als erwartet wird. Daher stellt sich die Frage: Wie partitioniere ich eine bestehende Tabelle?<\/p>\n<p>Gr\u00fcnds\u00e4tzlich k\u00f6nnte man die bestehende Tabelle auslagern, neu erstellen und dann wieder alle Daten reinkopieren. Das ist u.U nicht immer ganz einfach, besonders dann, wenn die Tabelle referentielle Integrit\u00e4ten besitzt (Fremdschl\u00fcssel, bzw. &#8222;Verlinkungen in andere Tabellen&#8220;) und man durch ein L\u00f6schen und Neuerstellen doch mehr Arbeit produziert, als notwendig.<\/p>\n<p>Zuerst erstellen wir uns die Umgebung (auf Basis des Beispiels von dem Artikel: <a href=\"http:\/\/www.flip-design.de\/?p=47\">Partitionierung von SQL Server Tabellen<\/a>):<br \/>\n<code>CREATE TABLE dbo.buchungen (<br \/>\n[uid] INT NOT NULL PRIMARY KEY,<br \/>\n[name] VARCHAR(50),<br \/>\n[datum] DATETIME DEFAULT GETDATE() NOT NULL,<br \/>\n[wert] MONEY);<br \/>\nGO<\/code><\/p>\n<p><code>CREATE TABLE dbo.buchungen_Log (<br \/>\n[uid] INT NOT NULL PRIMARY KEY,<br \/>\n[buchungen_uid] INT NOT NULL);<br \/>\nGO<\/code><\/p>\n<p><code><code>ALTER TABLE dbo.buchungen_Log ADD CONSTRAINT FK_buchungen_Log_buchungen FOREIGN KEY<br \/>\n(buchungen_uid) REFERENCES dbo.buchungen<br \/>\n(uid)<br \/>\nGO<\/code><\/code><\/p>\n<p><code> <\/code><\/p>\n<p><code>INSERT INTO dbo.buchungen (uid, name, datum, wert) VALUES (1, 'Januar 2008', '20080308', '100');<br \/>\nINSERT INTO dbo.buchungen (uid, name, datum, wert) VALUES (2, 'M\u00e4rz 2009', '20090308', '100');<br \/>\nINSERT INTO dbo.buchungen (uid, name, datum, wert) VALUES (3, 'Februar 2010', '20100209', '100');<br \/>\nINSERT INTO dbo.buchungen (uid, name, datum, wert) VALUES (4, 'Januar 2011', '20110120', '100');<br \/>\nINSERT INTO dbo.buchungen (uid, name, datum, wert) VALUES (5, 'Januar 2012', '20120115', '300');<br \/>\nGO<br \/>\nINSERT INTO dbo.buchungen_Log (uid, buchungen_uid) VALUES (1, 1);<br \/>\nINSERT INTO dbo.buchungen_Log (uid, buchungen_uid) VALUES (2, 2);<br \/>\nINSERT INTO dbo.buchungen_Log (uid, buchungen_uid) VALUES (3, 3);<br \/>\nINSERT INTO dbo.buchungen_Log (uid, buchungen_uid) VALUES (4, 4);<br \/>\nINSERT INTO dbo.buchungen_Log (uid, buchungen_uid) VALUES (5, 5);<br \/>\nGO<\/code><\/p>\n<p>Nun haben wir die Tabelle &#8222;Buchungen&#8220; die die zu partitionierenden Daten enth\u00e4lt und auch den Fremschl\u00fcssel f\u00fcr die Tabelle &#8222;buchungen_log&#8220; stellt.<br \/>\nAnsich geht man nun wir bei der Partitionierung einer neuen Tabelle vor, indem man zuerst die Dateigruppen und die jeweiligen Dateien erstellt:<\/p>\n<p><code>ALTER DATABASE [Produktion] ADD FILEGROUP [Archiv2009]<br \/>\nALTER DATABASE [Produktion] ADD FILEGROUP [Archiv2010]<br \/>\nALTER DATABASE [Produktion] ADD FILEGROUP [Archiv2011]<br \/>\nALTER DATABASE [Produktion] ADD FILEGROUP [Archiv2012]<br \/>\nALTER DATABASE [Produktion] ADD FILEGROUP [Archiv]<br \/>\nGO<\/code><\/p>\n<p><code> <\/code><\/p>\n<p><code>ALTER DATABASE [Produktion] ADD FILE ( NAME = N'2009',<br \/>\nFILENAME = N'C:\\Program Files\\Microsoft SQL Server\\MSSQL10_50.SQL1\\MSSQL\\DATA\\2009.ndf',<br \/>\nSIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP [Archiv2009]<br \/>\nGO<br \/>\nALTER DATABASE [Produktion] ADD FILE ( NAME = N'2010',<br \/>\nFILENAME = N'C:\\Program Files\\Microsoft SQL Server\\MSSQL10_50.SQL1\\MSSQL\\DATA\\2010.ndf',<br \/>\nSIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP [Archiv2010]<br \/>\nGO<br \/>\nALTER DATABASE [Produktion] ADD FILE ( NAME = N'2011',<br \/>\nFILENAME = N'C:\\Program Files\\Microsoft SQL Server\\MSSQL10_50.SQL1\\MSSQL\\DATA\\2011.ndf',<br \/>\nSIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP [Archiv2011]<br \/>\nGO<br \/>\nALTER DATABASE [Produktion] ADD FILE ( NAME = N'2012',<br \/>\nFILENAME = N'C:\\Program Files\\Microsoft SQL Server\\MSSQL10_50.SQL1\\MSSQL\\DATA\\2012.ndf',<br \/>\nSIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP [Archiv2012]<br \/>\nGO<br \/>\nALTER DATABASE [Produktion] ADD FILE ( NAME = N'Archiv',<br \/>\nFILENAME = N'C:\\Program Files\\Microsoft SQL Server\\MSSQL10_50.SQL1\\MSSQL\\DATA\\Archiv.ndf',<br \/>\nSIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP [Archiv]<br \/>\nGO <\/code><\/p>\n<p>Nun ben\u00f6tigt man die Partitionierungs-Funktion und das Schema f\u00fcr die Datenverteilung:<br \/>\n<code>ALTER DATABASE [Produktion] ADD FILEGROUP [Archiv2009]<br \/>\nALTER DATABASE [Produktion] ADD FILEGROUP [Archiv2010]<br \/>\nALTER DATABASE [Produktion] ADD FILEGROUP [Archiv2011]<br \/>\nALTER DATABASE [Produktion] ADD FILEGROUP [Archiv2012]<br \/>\nALTER DATABASE [Produktion] ADD FILEGROUP [Archiv]<br \/>\nGO<\/code><\/p>\n<p><code> <\/code><\/p>\n<p><code>ALTER DATABASE [Produktion] ADD FILE ( NAME = N'2009',<br \/>\nFILENAME = N'C:\\Program Files\\Microsoft SQL Server\\MSSQL10_50.SQL1\\MSSQL\\DATA\\2009.ndf' ,<br \/>\nSIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP [Archiv2009]<br \/>\nGO<br \/>\nALTER DATABASE [Produktion] ADD FILE ( NAME = N'2010',<br \/>\nFILENAME = N'C:\\Program Files\\Microsoft SQL Server\\MSSQL10_50.SQL1\\MSSQL\\DATA\\2010.ndf' ,<br \/>\nSIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP [Archiv2010]<br \/>\nGO<br \/>\nALTER DATABASE [Produktion] ADD FILE ( NAME = N'2011',<br \/>\nFILENAME = N'C:\\Program Files\\Microsoft SQL Server\\MSSQL10_50.SQL1\\MSSQL\\DATA\\2011.ndf' ,<br \/>\nSIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP [Archiv2011]<br \/>\nGO<br \/>\nALTER DATABASE [Produktion] ADD FILE ( NAME = N'2012',<br \/>\nFILENAME = N'C:\\Program Files\\Microsoft SQL Server\\MSSQL10_50.SQL1\\MSSQL\\DATA\\2012.ndf' ,<br \/>\nSIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP [Archiv2012]<br \/>\nGO<br \/>\nALTER DATABASE [Produktion] ADD FILE ( NAME = N'Archiv',<br \/>\nFILENAME = N'C:\\Program Files\\Microsoft SQL Server\\MSSQL10_50.SQL1\\MSSQL\\DATA\\Archiv.ndf',<br \/>\nSIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP [Archiv]<br \/>\nGO <\/code><\/p>\n<p>Nun wird die Partionierungsfunktion wie auch das Schema erstellt, um die Datentrennung zu regeln:<br \/>\n<code>CREATE PARTITION FUNCTION ArchivierungsFunktion (DATETIME) AS RANGE RIGHT<br \/>\nFOR VALUES (<br \/>\n'20090101' -- Kleiner als 01.01.2009<br \/>\n, '20100101' -- Kleiner als 01.01.2010, gr\u00f6\u00dfer als 01.01.2009<br \/>\n, '20110101' -- Kleiner als 01.01.2011, gr\u00f6\u00dfer als 01.01.2010<br \/>\n, '20120101' -- Kleiner als 01.01.2012, gr\u00f6\u00dfer als 01.01.2011<br \/>\n); <\/code><\/p>\n<p><code> <\/code><\/p>\n<p><code>CREATE PARTITION SCHEME ArchivierungsSchema AS PARTITION ArchivierungsFunktion<br \/>\nTO ('Archiv', 'Archiv2009', 'Archiv2010', 'Archiv2011', 'Archiv2012');<\/code><\/p>\n<p>Nun ben\u00f6tigt man einen Prim\u00e4r Schl\u00fcssel, wo jedoch auch das Datums Feld (Kennzeichen f\u00fcr die Partionierung) enthalten ist. Daf\u00fcr muss jedoch der Schl\u00fcssel erstmal entfernt werden, wie auch die Fremschl\u00fcssel Verbindung:<br \/>\n<code>ALTER TABLE [dbo].[buchungen_Log] DROP CONSTRAINT [FK_buchungen_Log_buchungen]<br \/>\nGO<br \/>\nALTER TABLE [dbo].[buchungen] DROP CONSTRAINT [PK__buchunge__DD7012647F60ED59]<br \/>\nGO<\/code><\/p>\n<p>Nun kann der Prim\u00e4rschl\u00fcssel erstellt werden, der dann an die Partionierungsfunktion geh\u00e4ngt wird (dieser muss ein Gruppierter Index sein, eine HEAP Tabelle (ohne Gruppierten Index) wird hier nicht unterst\u00fctzt, da die Daten sonst nicht verschoben werden k\u00f6nnen):<br \/>\n<code>ALTER TABLE dbo.buchungen ADD CONSTRAINT<br \/>\nPK_buchungen PRIMARY KEY CLUSTERED<br \/>\n([uid], [datum]) on ArchivierungsSchema(datum);<\/code><\/p>\n<p>Kontrolliert werden kann dies folgenderma\u00dfen:<br \/>\n<code>SELECT<br \/>\nsys.filegroups.name 'Partitionsname' , sys.partitions.rows 'Zeilenanzahl'<br \/>\nFROM<br \/>\nsys.partitions INNER JOIN sys.allocation_units<br \/>\nON sys.allocation_units.container_id = sys.partitions.hobt_id<br \/>\nINNER JOIN sys.filegroups ON sys.filegroups.data_space_id = sys.allocation_units.data_space_id<br \/>\nWHERE sys.partitions.object_id = OBJECT_ID('dbo.buchungen') <\/code><\/p>\n<p>Das wars.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In dem Artikel Partitionierung von SQL Server Tabellen habe ich bereits beschrieben, wie man die Partionierung auf eine neue Tabelle anwendet. In der Praxis f\u00fchrt man solche Technologien doch eher an bestehenden Tabellen ein, wenn man merkt, das die Tabelle &hellip; <a href=\"https:\/\/www.flip-design.de\/?p=129\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[18,9,10,3],"tags":[],"_links":{"self":[{"href":"https:\/\/www.flip-design.de\/index.php?rest_route=\/wp\/v2\/posts\/129"}],"collection":[{"href":"https:\/\/www.flip-design.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.flip-design.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.flip-design.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.flip-design.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=129"}],"version-history":[{"count":4,"href":"https:\/\/www.flip-design.de\/index.php?rest_route=\/wp\/v2\/posts\/129\/revisions"}],"predecessor-version":[{"id":143,"href":"https:\/\/www.flip-design.de\/index.php?rest_route=\/wp\/v2\/posts\/129\/revisions\/143"}],"wp:attachment":[{"href":"https:\/\/www.flip-design.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=129"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.flip-design.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=129"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.flip-design.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=129"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}