Avatar billede mysitesolution Nybegynder
06. marts 2008 - 19:28 Der er 27 kommentarer og
1 løsning

Problemstilling omkring unikke ID, og performance

Hej...

Jeg har en tabel der ser ud som denne:

Unikke ID, Ejer ID, Bilag ID
1,1,1
2,1,2
3,2,1
4,1,3
5,3,1
6,3,2

Håber i kan se idéen i det. Altså har et unikt ID, som man jo normalt har når der ikke er andet unikt. Og så har jeg et ejer id som kan fremkomme igen og igen. Der er så bilag til hver ejer id, og disse er unikke for hver ejer.

Mit spørgsmål er så:
Når jeg skal lave en insert, så skal jeg finde ud af hvad det næste bilag id vil blive, og det kan jo gøres med noget select count og where ejer id=[ejer id]. Er dette effektivt nok, eller er der en anden måde?

Er der en bedre måde at strukturere tabellen på?
Avatar billede erikjacobsen Ekspert
06. marts 2008 - 19:33 #1
Du skal jo formentlig have et index på ejerid. Men du kan jo behøver ikke bilagsnummeret i denne tabel - den kunne stå i bilagstabellen.

(Jeg kan ikke rådgive dig, kun komme med forslag)
Avatar billede martinlind Nybegynder
06. marts 2008 - 19:37 #2
evt. bruge autoinc istedet for select count...
Avatar billede mysitesolution Nybegynder
06. marts 2008 - 19:41 #3
erikjacobsen->indeks ja, men selvom jeg laver en bilagstabel, så vil ejer id jo stadig være der, og så er jeg lige vidt.

martinlind->Fik vidst ikke forklaret mig ordentligt.. der er autoinc på unikke id, men kan jeg jo ikke sætte på for bilag id?
Avatar billede mysitesolution Nybegynder
06. marts 2008 - 19:44 #4
erikjacobsen->så skulle jeg jo lave en tabel for hvert ejer id, men det kan da umuligt være performant hvis der er 10.000 ejer id'er
Avatar billede arne_v Ekspert
06. marts 2008 - 19:54 #5
At finde stoerste bilag id og ligge 1 til er en jammerlig metode som vil give store
problemer den dag der skal flere samtidige brugere paa.

Umiddelbart vil jeg foreslaa:

ejer
----
ejerid, PK, auto
...

bilag
-----
ejerid, PK, FK
bilagid, PK, auto
...

En PK med 2 felter har visse ulemper med i dette tilfaelde tror jeg at det er den
nemmeste loesning.
Avatar billede mysitesolution Nybegynder
06. marts 2008 - 19:57 #6
arne_v-> er lidt i tvivl om din løsning... Når en "ejer" der har 2 bilag i forvejen, laver et bilag skal det blive nr. 3. Med din løsning, vil det så ikke blive nr. 5 hvis nu en anden ejer også har 2 bilag?
Avatar billede arne_v Ekspert
06. marts 2008 - 20:04 #7
jo - du har ret
Avatar billede mysitesolution Nybegynder
06. marts 2008 - 20:08 #8
du har ikke en anden løsning så? og for resten til "den dag der skal flere samtidige brugere paa" - den dag er i dag ;)
Avatar billede mysitesolution Nybegynder
06. marts 2008 - 20:13 #9
Der er ikke en indbygget database funktion, som finder et specifikt id set sammen med et andet id. Jeg mener, det kan da umuligt kun være mig der har denne problemstilling?
Avatar billede arne_v Ekspert
06. marts 2008 - 20:14 #10
Jeg tror at du skal have en multi sequence tabel saa.

ejer
----
ejerid, PK, auto
...

bilag
-----
ejerid, PK, FK
bilagid, PK
...

multiseq
--------
ejerid, PK, FK
currbilagid

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
SELECT currbilagid FROM multiseq
UPDATE multiseq SET currbilagid = currbilagid
INSERT bilag
COMMIT
Avatar billede arne_v Ekspert
06. marts 2008 - 20:14 #11
hov

UPDATE multiseq SET currbilagid = currbilagid + 1

naturligvis.
Avatar billede arne_v Ekspert
06. marts 2008 - 20:18 #12
transaction isolation level serializable koster i performance

alternativet er en database specifik noshare (exclusive) lock paa den raekke i multiseq
Avatar billede mysitesolution Nybegynder
06. marts 2008 - 20:19 #13
ja altså noget i retningen af:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
SELECT currbilagid FROM multiseq
UPDATE multiseq SET currbilagid = currbilagid + 1
INSERT bilag (bilagid) values (currbilagid)
COMMIT
Avatar billede mysitesolution Nybegynder
06. marts 2008 - 20:20 #14
er ved at installere en ms sql server på min computer.. Kan du så gøre det mere effektivt hvis jeg siger det er ms sql server?

Hvor meget performance koster det?
Avatar billede arne_v Ekspert
06. marts 2008 - 20:25 #15
Jeg kommer lige i tanke om. Du behoever ikke SERIALIZABLE. REPEATABLE READ er nok. Det
er saadan set hele grunden til at jeg foreslog den separate tabel fremfor SELECT MAX+1.
Avatar billede arne_v Ekspert
06. marts 2008 - 20:26 #16
Med hensyn til hvad det koster, saa kan jeg kun foreslaa dig at lave noget test
(med REPEATABLE READ).
Avatar billede arne_v Ekspert
06. marts 2008 - 20:27 #17
Med hensyn til de SQLServer specifikke loesninger vil jeg vaere noedt til at checke
i dokumentationen.
Avatar billede erikjacobsen Ekspert
06. marts 2008 - 21:03 #18
I ejer tabellen kunne du have kundens max bilagsnummer. Der er derved en smule redundans i databasen - men det går nok.
Avatar billede mysitesolution Nybegynder
06. marts 2008 - 23:49 #19
Så er jeg tilbage igen...

arne_v->Hvad siger du til erikjacobsens sidste kommentar? Er det noget jeg skulle gøre, eller er det den bedste praksis at have det separart?
Avatar billede mysitesolution Nybegynder
06. marts 2008 - 23:52 #20
anyway, vi er vidst snart nået til en konklusion.. så smid svar arne_v og erikjacobsen
Avatar billede erikjacobsen Ekspert
07. marts 2008 - 00:19 #21
Du skal selvfølgelig pakke den ind i en transaktion og passende isolation level.
Jeg samler slet ikke på point, tak.
Avatar billede arne_v Ekspert
07. marts 2008 - 04:22 #22
Eriks løsning er meget tæt op min. Hans ejer.maxbilagid svarer til min multiseq.currbilagid - forskellen er at jeg har brugt en separat tabel mens
han bare har brugt ejer tabellen.

Hvorfor har jeg lavet den separate tabel ? Godt spørgsmål - jeg er ikke i tvivl om
at jeg selv ville lave det med separat tabel. Men argumenterne er lidt luftige.
Jeg vil helst have at ejer tabellen er en model af ejers faktiske egenskaber, mens
det største bilags id er en ren teknisk utility ting.
Avatar billede arne_v Ekspert
07. marts 2008 - 04:25 #23
Med hensyn til SQLServer specifikke muligheder, så fandt jeg noget gammelt kode med:

BEGIN
SELECT f FROM t WITH (TABLOCKX) WHERE id = ?
UPDATE t SET f = ? WHERE id = ?
COMMIT

Jeg tror at et lavt transaction isolation level kombineret med WITH (TABLOCKX) på
den SELECT vil virke lige så godt som transaction isolation level read repeatable
på SQLServer.
Avatar billede arne_v Ekspert
07. marts 2008 - 04:25 #24
og et svar
Avatar billede arne_v Ekspert
07. marts 2008 - 04:30 #25
Med TABLOCKX kunne der være yderlige en grund til en separat tabel, da vi kun
ønsker at låse på bilags id.
Avatar billede mysitesolution Nybegynder
10. marts 2008 - 16:08 #26
Hvis du stadig ser det her:

Hvorfor er det egentlig at begge er primær?

bilag
-----
ejerid, PK, FK
bilagid, PK
Avatar billede mysitesolution Nybegynder
10. marts 2008 - 16:14 #27
Nej lige meget, kan jeg da godt se hvorfor :)
Avatar billede arne_v Ekspert
10. marts 2008 - 16:33 #28
:-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester