Avatar billede or.han Nybegynder
17. juli 2007 - 13:20 Der er 13 kommentarer og
1 løsning

Bedst mulige design af forespørgsel

Hey

Jeg har en tabel som hedder "Links". Dens kolonner er id, object1_id og object2_id.

id: primær nøgle
object1_id: en fremmednøgle fra tabellen "Objects"
object2_id: en fremmednøgle fra tabellen "Objects"

Meningen med tabellen "Links" er at angive en forbindelse mellem to forskellige objekter. Objekter kan være forskellige ting, for eksempel: Apple og iPod. Disse to objekter er "forbundet", da det er Apple, som har lavet iPod'en. I "Links" gemmes derfor objektet Apple's id og objektet iPod's id.

Det jeg så ønsker er, at man eksempelvis kan søge efter alt som har en relation til Apple. Det er nemt nok, men det er jo ikke fastlagt om Apple's id står i "object1_id" eller "object2_id".

Kan man overhovedet lave en forespørgsel, som kun returnerer en kolonne med de objekter, som det søgte objekt har en relation til? Den eneste løsning jeg kan komme på er at bytte om "objekt1_id" og "objekt2_id" nogle steder, så de kommer til at stå rigtigt, men den løsning er lidt for "hjemmelavet" synes jeg.

Jeg forklarer gerne yderligere, hvis I ikke helt forstår ideen.
Avatar billede pgroen Nybegynder
17. juli 2007 - 14:55 #1
Hvis jeg forstår dig ret, så vil du gøre noget i stil med:

SELECT links.id
  FROM links
WHERE (  links.object1_id = objects.id
        OR links.object2_id = objects.id)
  AND objects.navn = 'Apple';

- men jeg fornemmer at det er mere kompliceret end som så... (?)
Avatar billede pgroen Nybegynder
17. juli 2007 - 14:57 #2
Hov, undskyld:

SELECT links.id
  FROM links, objects
WHERE (  links.object1_id = objects.id
        OR links.object2_id = objects.id)
  AND objects.navn = 'Apple';
Avatar billede or.han Nybegynder
17. juli 2007 - 14:57 #3
Jeg kan sagtens finde hvor et bestemt objekt har en relation. Det kan gøres med følgende forespørgsel:
SELECT id
FROM Links
WHERE object1_id = [ObjId] OR object2_id = [ObjId];

ObjId er bare en parameter.

Hvordan kan jeg så få returneret kun én kolonne indeholdende det relaterende objekts id?
Avatar billede teepee Nybegynder
17. juli 2007 - 14:57 #4
Når du skal fremsøge links kan du enten bruge;
select *
from links
where object1_id=xxx or object2_id=xxx
... eller du kan lave en union all ...
select *
from links
where object1_id=xxx
union all
select *
from links
where object2_id=xxx
sidstnævnte vil give nogle dubletter hvis objekter kan linke til sig selv, men ellers vil den ofte give bedre performance hvis du skal have flere kirterier på din sql
Avatar billede teepee Nybegynder
17. juli 2007 - 14:58 #5
I øvrigt er en dummy primærnøgle ikke nødvendig på sådan en tabel, den kan faktisk godt bestå af de to foreign keys felter
Avatar billede or.han Nybegynder
17. juli 2007 - 15:00 #6
Hehe så ikke din post.

Søgningen sker efter objektets id, så der skal ikke tages højde for noget med navnet. Men ja den forespørgsel du skriver returnerer relationernes id'er. Men jeg vil kun have returneret det relaterende objekts id.
Avatar billede martinlind Nybegynder
17. juli 2007 - 15:14 #7
kan du ikke lave et lille eks. på hvad du har af data og hvad du gerne vil ha' ud, måske det kan lette forståelsen :)
Avatar billede or.han Nybegynder
17. juli 2007 - 15:16 #8
Union er nok den bedste løsning. Objekter kan ikke linke til sig selv, så det er jo helt fint.
Der er en primærnøgle fordi relationen bruges i sammenhæng med andre tabeller.

Jeg har i denne sammenhæng et mindre spørgsmål. Links' primærnøgle bruges eksempelvis sammen med tabellen LinkNotes. Man kan altså kommentere relationen. Der er også andre tabeller som bruges til noter/kommentarer. Der er fx ObjectNotes, som kan bruges til at kommentere selve objektet.

Mit spørgsmål er så om det er smartest at have flere tabeller til kommentarer eller om det er bedst med én global tabel til alle kommentarer. En global tabel vil selvfølgelig kræve et ekstra felt som angiver hvilken tabel den hører til, fx objects eller links. Ved ikke lige hvad der er mest "korrekt"...
Avatar billede or.han Nybegynder
17. juli 2007 - 15:22 #9
Har ikke afprøvet teepee's løsning men det ser rigtigt nok ud med union.

Links-tabellen:
id, object1_id, object2_id
1, 4, 7
2, 6, 8
3, 9, 3
4, 10, 4

Objects-tabellen:
id, name
3, Microsoft
4, Apple
6, Photoshop
7, iPod
8, Adobe
9, Office
10, iMac

Sådan kan tabellen eksempelvis se ud. Så ønsker jeg fx at finde alle objekter som har forbindelse til Apple. Så det jeg vil have returneret er:
7
10

Disse to id'er tilhører hhv. iPod og iMac. Lettere at forstå nu?
Avatar billede or.han Nybegynder
17. juli 2007 - 15:27 #10
teepee>> Har lovet din løsning lidt om:

SELECT object1_id AS [Linked object id]
FROM Links
WHERE object2_id = #ObjId_parameter
UNION
SELECT object2_id AS [Linked object id]
FROM Links
WHERE object1_id = #ObjId_parameter

Afprøver senere, men tror det vil virke.
Avatar billede or.han Nybegynder
17. juli 2007 - 15:28 #11
lavet i stedet for lovet
Avatar billede or.han Nybegynder
18. juli 2007 - 12:45 #12
Jeg har i denne sammenhæng et mindre spørgsmål. Links' primærnøgle bruges eksempelvis sammen med tabellen LinkNotes. Man kan altså kommentere relationen. Der er også andre tabeller som bruges til noter/kommentarer. Der er fx ObjectNotes, som kan bruges til at kommentere selve objektet.

Mit spørgsmål er så om det er smartest at have flere tabeller til kommentarer eller om det er bedst med én global tabel til alle kommentarer. En global tabel vil selvfølgelig kræve et ekstra felt som angiver hvilken tabel den hører til, fx objects eller links. Ved ikke lige hvad der er mest "korrekt"...
Avatar billede teepee Nybegynder
19. juli 2007 - 09:10 #13
Det kommer nok an på hvordan du har tænkt dig at bruge tabellen. Hvis den skal joines runtime med de tabeller som noterne hører til, så lav individuelle tabeller, men rigtige fremmednøgler. Hvis det skal være selvstændige opslag, kan du godt nøjes med en fælles tabel.
Avatar billede or.han Nybegynder
19. juli 2007 - 15:35 #14
Der er flere noter/kommentarer til hvert objekt/link osv, så de skal ikke direkte joines. De er lidt separate fra selve objektet/linket, så det er nok mest optimalt med en fælles tabel. Mange tak for hjælpen!
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