Welcome to Sign in | Help

Re: Baza de date cu structura necunoscuta

  •  10-25-2009, 3:06 AM

    Re: Baza de date cu structura necunoscuta

    [1] Dacă este vorba de SQL2008 atunci sparse columns (dupa cum a recomandat si Andrei).
    Uite o comparatie sparse columns vs. XML netipizat vs. XML tipizat.
    La mine scorul a fost următorul:
    sparse columns  80.922 MB
    XML netipizat  140.484 MB
    XML tipizat    181.703 MB


    CREATE TABLE Persoana1
    (
      IDPersoana INT IDENTITY(1,1) PRIMARY KEY,
      Nume VARCHAR(50) NOT NULL,
      DataNasterii DATETIME SPARSE NULL,
      Greutate DECIMAL SPARSE NULL,
      Nevasta VARCHAR(50) SPARSE NULL,
      Copii INT SPARSE NULL
    );
    GO

    CREATE TABLE Persoana2
    (
      IDPersoana INT PRIMARY KEY,
      Nume VARCHAR(50) NOT NULL,
      Alte XML NOT NULL
    );
    GO

    CREATE XML SCHEMA COLLECTION XMLAlte AS
    '<?xml version="1.0" encoding="utf-8" ?>
    <xs:schema blockDefault="" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:complexType name="TipAlteInformatii">
    <xs:choice>
    <xs:element name="DataNasterii" type="xs:string" />
    <xs:element name="Greutate" type="xs:decimal" />
    <xs:sequence>
    <xs:element name="Nevasta" type="xs:string" />
    <xs:element name="Copii" type="xs:integer" />
    </xs:sequence>
    </xs:choice>
    </xs:complexType>
    <xs:element name="Alte" type="TipAlteInformatii" />
    </xs:schema>'
    ;
    GO

    CREATE TABLE Persoana3
    (
      IDPersoana INT PRIMARY KEY,
      Nume VARCHAR(50) NOT NULL,
      Alte XML (XMLAlte) NOT NULL
    );
    GO

    DECLARE @i INT
    SET @i=1
    WHILE @i <= 1000000
    BEGIN
      DECLARE @tipPersoana INT
      SET @tipPersoana = ABS( CAST( CAST( NEWID() AS VARBINARY ) AS INT) )
      IF @tipPersoana % 3 = 0
        INSERT INTO Persoana1 ( Nume, DataNasterii ) VALUES ( NEWID(), CAST( CAST( CAST( NEWID() AS VARBINARY ) AS SMALLINT ) AS DATETIME ) )
      ELSE
      IF @tipPersoana % 3 = 1
        INSERT INTO Persoana1 ( Nume, Greutate ) VALUES ( NEWID(), CAST( RAND()*1000000 AS INT )%100 )
      ELSE
      IF @tipPersoana % 3 = 2
        INSERT INTO Persoana1 ( Nume, Nevasta, Copii ) VALUES ( NEWID() , NEWID() , CAST( RAND()*1000000 AS INT )%10 )
      
      SET @i = @i + 1
    END
    GO
    SELECT COUNT(*) AS NrTabelaPersoana1 FROM Persoana1
    GO

    INSERT INTO Persoana2
    SELECT IDPersoana,
      Nume,
      '<Alte>'+
      CASE
      WHEN DataNasterii IS NOT NULL THEN '<DataNasterii>'+CAST(DataNasterii AS VARCHAR(25))+'</DataNasterii>'
      WHEN Greutate IS NOT NULL THEN '<Greutate>'+CAST(Greutate AS VARCHAR(25))+'</Greutate>'
      WHEN Nevasta IS NOT NULL THEN '<Nevasta>'+Nevasta+'</Nevasta> <Copii>'+CAST(Copii AS VARCHAR(2))+'</Copii>'
      END+
      '</Alte>'
    FROM Persoana1
    GO
    SELECT COUNT(*) AS NrTabelaPersoana2 FROM Persoana2
    GO

    INSERT INTO Persoana3 (IDPersoana,Nume,Alte)
    SELECT IDPersoana,
      Nume,
      '<Alte>'+
      CASE
      WHEN DataNasterii IS NOT NULL THEN '<DataNasterii>'+CAST(DataNasterii AS VARCHAR(25))+'</DataNasterii>'
      WHEN Greutate IS NOT NULL THEN '<Greutate>'+CAST(Greutate AS VARCHAR(25))+'</Greutate>'
      WHEN Nevasta IS NOT NULL THEN '<Nevasta>'+Nevasta+'</Nevasta> <Copii>'+CAST(Copii AS VARCHAR(2))+'</Copii>'
      END+
      '</Alte>'
    FROM Persoana1
    GO
    SELECT COUNT(*) AS NrTabelaPersoana3 FROM Persoana3
    GO

    EXEC sp_spaceused 'dbo.Persoana1'
    EXEC sp_spaceused 'dbo.Persoana2'
    EXEC sp_spaceused 'dbo.Persoana3'


    [2] Pentru SQL < 2008 : partitionare pe orizantala > trei tabele separate + view cu union all + eventual triger-e INSTEAD OF INSERT/ DELETE/ UPDATE
View Complete Thread
Powered by Community Server (Commercial Edition), by Telligent Systems