Tabela z wieksza iloscia niz 16 pól - projetowanie bazy

0

Cześć,

mam taki model w firmie, że laduje do bazy tabele z csv, która ma okolo 18 pól.
Nie ma tam primary key.

Pracuję na MS Access, ale pytanie jest ogólnie o konstrukcje baz danych.

Na accessie można tak importować dane bez key'a:
http://www.mendipdatasystems.co.uk/synchronise-data-2/4594514002

Napisałem takiego SQLka, aby wyeliminować nulle i sprawdzić co jest w jednej tabeli a czego nie ma w drugiej:

SELECT DISTINCT * 
FROM   tblvolumes AS t2 
       LEFT JOIN qryim_sourcevolumes AS t1 
              ON ( t2.percentsnapshotspace = t1.percentsnapshotspace 
                    OR ( t2.percentsnapshotspace IS NULL 
                         AND t1.percentsnapshotspace IS NULL ) ) 
                 AND ( t2.filesystemtype = t1.filesystemtype 
                        OR ( t2.filesystemtype IS NULL 
                             AND t1.filesystemtype IS NULL ) ) 
                 AND ( t2.disknumber = t1.disknumber 
                        OR ( t2.disknumber IS NULL 
                             AND t1.disknumber IS NULL ) ) 
                 AND ( t2.volumenameidfk = t1.volumenameidfk 
                        OR ( t2.volumenameidfk IS NULL 
                             AND t1.volumenameidfk IS NULL ) ) 
                 AND ( t2.physicaldiskmodelidfk = t1.physicaldiskmodelidfk 
                        OR ( t2.physicaldiskmodelidfk IS NULL 
                             AND t1.physicaldiskmodelidfk IS NULL ) ) 
                 AND ( t2.tierid = t1.tierid 
                        OR ( t2.tierid IS NULL 
                             AND t1.tierid IS NULL ) ) 
                 AND ( t2.ordinal = t1.ordinal 
                        OR ( t2.ordinal IS NULL 
                             AND t1.ordinal IS NULL ) ) 
                 AND ( t2.environmentid = t1.environmentid 
                        OR ( t2.environmentid IS NULL 
                             AND t1.environmentid IS NULL ) ) 
                 AND ( t2.sharemode = t1.sharemode 
                        OR ( t2.sharemode IS NULL 
                             AND t1.sharemode IS NULL ) ) 
                 AND ( t2.subjectcomponent = t1.subjectcomponent 
                        OR ( t2.subjectcomponent IS NULL 
                             AND t1.subjectcomponent IS NULL ) ) 
                 AND ( t2.formatcommand = t1.formatcommand 
                        OR ( t2.formatcommand IS NULL 
                             AND t1.formatcommand IS NULL ) ) 
                 AND ( t2.description = t1.description 
                        OR ( t2.description IS NULL 
                             AND t1.description IS NULL ) ) 
                 AND ( t2.function = t1.function 
                        OR ( t2.function IS NULL 
                             AND t1.function IS NULL ) ) 
                 AND ( t2.caching = t1.caching 
                        OR ( t2.caching IS NULL 
                             AND t1.caching IS NULL ) ) 
                 AND ( t2.writeacceleratorenabled = t1.writeacceleratorenabled 
                        OR ( t2.writeacceleratorenabled IS NULL 
                             AND t1.writeacceleratorenabled IS NULL ) ) 
                 AND ( t2.caching = t1.caching 
                        OR ( t2.caching IS NULL 
                             AND t1.caching IS NULL ) ) 
WHERE  ( ( ( t1.ordinal ) IS NULL ) 
         AND ( ( t1.environmentid ) IS NULL ) 
         AND ( ( t1.tierid ) IS NULL ) 
         AND ( ( t1.physicaldiskmodelidfk ) IS NULL ) 
         AND ( ( t1.volumenameidfk ) IS NULL ) 
         AND ( ( t1.disknumber ) IS NULL ) 
         AND ( ( t1.filesystemtype ) IS NULL ) 
         AND ( ( t1.percentsnapshotspace ) IS NULL ) 
         AND ( ( t1.sharemode ) IS NULL ) 
         AND ( ( t1.subjectcomponent ) IS NULL ) 
         AND ( ( t1.formatcommand ) IS NULL ) 
         AND ( ( t1.description ) IS NULL ) 
         AND ( ( t1.function ) IS NULL ) 
         AND ( ( t1.caching ) IS NULL ) 
         AND ( ( t1.writeacceleratorenabled ) IS NULL ) );

I teraz pytanie - bo usłyszałem, że mam beznadziejnie zaprojektowany model - czy tak jest naprawdę?
Czy pracujecie też na tabelach które maja wiecej niz 15 pól?
Co jest w tym zlego ze dostaje dane w pliku csv bez key'a ?

Podpowiedźcie proszę,
Jacek

0
jaryszek napisał(a):

I teraz pytanie - bo usłyszałem, że mam beznadziejnie zaprojektowany model - czy tak jest naprawdę?

Masz na myśli budowę tabelki? Ciężko zgadywać, skoro nie podałeś nam jak wygląda jej budowa, tylko jakąś sqlkę, którą się ciężko czyta.

jaryszek napisał(a):

Czy pracujecie też na tabelach które maja wiecej niz 15 pól?

15 pól to w sumie nic wielkiego. Wszystko zależy od tego, czego te pola dotyczą. Może i być pól dużo więcej, takich co ciężko rozbić na osobne tabelki.

0

Dziękuję.

Budowa tabelki jak budowa tabelki - to co napisaleś @serek - tutaj jest ciezko rozbic na osobne tabelki wiec nie wiem czemu sie przyburał na podstawie wlasnie tylko jednego sqlka.

Jacek

0

Jakbyś wrzucił nam schemę z tabeli, to byłoby łatwiej.

Na pierwszy rzut oka to mogę jedynie stwierdzić, że chętnie bym udusił kogoś, kto nazywa kolumny ciągiem, czyli writeacceleratorenabled, zamiast is_write_accelerator_enabled

0

Uwierz, pracowałem na tabelach, które miały kilkadziesiąt pól, 20 jest spoko.
CSV bez id to też całkiem normalna sprawa.

0

ilość kolumn pikuś, ale ilości warunków w JOIN ON w życiu tyle nie widziałem. Gdyby przypuścić że na zasadzie XY Problem to ma leczyć wcześniejszą słabość projektu, to masz swoją odpowiedź.

0

O ja oO Ja tylko przelotnie zerknąłem na tą SQLkę, to założyłem, że te warunki są z where oO No to w takim razie z tym joinem to mocno poleciałeś^^

0

@serek jakie dane takie zapytanie inaczej się nie da,

@jaryszek
dwie uwagi do zapytania, możesz je uprościć (zakładając że puszczasz je w accessie)
Jak nie masz punktu zaczepienia między tabelami, to ja bym wyliczał np. md5 dla rekordu i porównywał wyliczone wartości
To oczywiście zależy od ilości danych, bo dla jakieś dużej wartości może to dobic Accessa.
Jeżeli jest ich strasznie dużo to użyj funkcji nz i wtedy:

( t2.percentsnapshotspace = t1.percentsnapshotspace 
                    OR ( t2.percentsnapshotspace IS NULL 
                         AND t1.percentsnapshotspace IS NULL ) ) 

możesz zastąpić:

 Nz(t2.percentsnapshotspace,"NULL") = Nz(t1.percentsnapshotspace,"NULL")

Dodatkowo zrobiłbym sztuczną kolumnę w podzapytanie, aby w where pytać tylko o jedna kolumnę

SELECT 
	DISTINCT * 
FROM
	(SELECT DISTINCT
		MD5_string(nz(ordinal,"NULL") & NZ(environmentid,"NULL") & NZ(tierid,"NULL") & NZ(physicaldiskmodelidfk,"NULL") & NZ(volumenameidfk,"NULL") & NZ(disknumber,"NULL") & NZ(filesystemtype,"NULL") & NZ(percentsnapshotspace,"NULL") & NZ(sharemode,"NULL") & NZ(subjectcomponent,"NULL") & NZ(formatcommand,"NULL") & NZ(description,"NULL") & NZ(function,"NULL") & NZ(caching,"NULL") & NZ(writeacceleratorenabled,"NULL")) AS MD5
		,*
	FROM
		tblvolumes) AS t2 
    LEFT JOIN (select DISTINCT
					"jestem" as obecny
					,MD5_string(nz(ordinal,"NULL") & NZ(environmentid,"NULL") & NZ(tierid,"NULL") & NZ(physicaldiskmodelidfk,"NULL") & NZ(volumenameidfk,"NULL") & NZ(disknumber,"NULL") & NZ(filesystemtype,"NULL") & NZ(percentsnapshotspace,"NULL") & NZ(sharemode,"NULL") & NZ(subjectcomponent,"NULL") & NZ(formatcommand,"NULL") & NZ(description,"NULL") & NZ(function,"NULL") & NZ(caching,"NULL") & NZ(writeacceleratorenabled,"NULL")) AS MD5
					, * 
				from 	
					qryim_sourcevolumes) AS t1 ON T1.MD5 = T2.MD5
WHERE  
    t1.obecny is null

Funkcje nd5_test możesz mieć stąd: https://www.di-mgt.com.au/src/basMD5.bas.html

1
Panczo napisał(a):

@serek jakie dane takie zapytanie inaczej się nie da,

No jasne. Syfu się nie przeskoczy niestety.

0

@serek ale jak zrobisz refaktor tabeli która jest wynikiem importu CSV? Pytam serio, bo nie bardzo widzę rozwiązanie...

1

Do znajdowania różnic między zbiorami (tabelami) służy przede wszystkim operacja MINUS. Pytanie czy Access to obsługuje.
Robisz dwie operacje:

SELECT k1, k2, k3 FROM tabela1
MINUS
SELECT k1, k2, k3 FROM tabela2;

SELECT k1, k2, k3 FROM tabela2
MINUS
SELECT k1, k2, k3 FROM tabela1;

Pierwsze zapytanie zwróci rekordy, które są w tabela1, ale nie ma ich w tabela2. Drugie - odwrotnie.

0

Dziękuję chłopaki za pomoc!

Tak, sql jest duzy niestety.

 Nz(t2.percentsnapshotspace,"NULL") = Nz(t1.percentsnapshotspace,"NULL")

@Panczo
To jest genialne!

[](http://)SELECT 
    DISTINCT * 
FROM
    (SELECT DISTINCT
        MD5_string(nz(ordinal,"NULL") & NZ(environmentid,"NULL") & NZ(tierid,"NULL") & NZ(physicaldiskmodelidfk,"NULL") & NZ(volumenameidfk,"NULL") & NZ(disknumber,"NULL") & NZ(filesystemtype,"NULL") & NZ(percentsnapshotspace,"NULL") & NZ(sharemode,"NULL") & NZ(subjectcomponent,"NULL") & NZ(formatcommand,"NULL") & NZ(description,"NULL") & NZ(function,"NULL") & NZ(caching,"NULL") & NZ(writeacceleratorenabled,"NULL")) AS MD5
        ,*
    FROM
        tblvolumes) AS t2 
    LEFT JOIN (select DISTINCT
                    "jestem" as obecny
                    ,MD5_string(nz(ordinal,"NULL") & NZ(environmentid,"NULL") & NZ(tierid,"NULL") & NZ(physicaldiskmodelidfk,"NULL") & NZ(volumenameidfk,"NULL") & NZ(disknumber,"NULL") & NZ(filesystemtype,"NULL") & NZ(percentsnapshotspace,"NULL") & NZ(sharemode,"NULL") & NZ(subjectcomponent,"NULL") & NZ(formatcommand,"NULL") & NZ(description,"NULL") & NZ(function,"NULL") & NZ(caching,"NULL") & NZ(writeacceleratorenabled,"NULL")) AS MD5
                    , * 
                from    
                    qryim_sourcevolumes) AS t1 ON T1.MD5 = T2.MD5
WHERE  
    t1.obecny is null
Funkcje

Tej funkcji nie do konca rozumiem. widze ze to MD5 to jest jakas zamiana na hashe.

Tutaj jest swietna opcja jak sobie poradzic z porownaniem za pomocą funkcji:
https://www.access-programmers.co.uk/forums/showthread.php?t=303677&page=5

ale hashe tez ciekawe

Pozdrowienia,
Jacek

2

Tej funkcji nie do konca rozumiem. widze ze to MD5 to jest jakas zamiana na hashe.

MD5 to funkcja którzy tworzy skrót, czyli łączymy wszystkie wartości z kolumn w jeden ciąg znaków (dla wartości null podstawiamy ciąg null) i porównujemy te skróty.
Efekt taki sam tylko czytelnie w joinie

1 użytkowników online, w tym zalogowanych: 0, gości: 1