[MySQL] Relational Friends Database

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Tharulerz
  • Registratie: April 2009
  • Laatst online: 10-04 05:16
Beste Mede-Tweakers,

Ik zit met het volgende probleem:

Voor een hobby project (waar ik helaas niet zoveel over kan vertellen) scrape ik vrij veel data van social network site X.

1 van deze types data zijn de zogenaamde 'friends relations'. Nu is het mij niet echt te doen om het datamodel (tenzij het echt fout zit) maar eerder de manier hoe ik het opsla.

Momenteel heb ik een tabel 'friends' met 2 kolommen:
- user
- friend

Beide kolommen zijn integers.

Momenteel scrape ik per user zijn friends, en die sla ik dan op in de vorm:

user1 -> vriend1
user1 -> vriend2
etc

Nu komt dus ooit het 'probleem' dat als je verder scraped je vrij snel tot een situatie komt als de volgende:

user25->vriend5

terwijl die omgekeerd er al in staat (vriend5 -> user25 dus).

Hoe pak je dit qua performance het beste aan? (Ik spreek over een aantal miljoenen records).

- Ga je elke keer als je een insert wil doen kijken of de omgekeerde relatie al bestaat? (Hier ga je dus dubbel zoveel queries doen, namelijk 1 select per insert?).
- Hou je alles gewoon dubbel bij? (Met vrij veel dubbele onnodige data, die bij miljoenen records misschien niet zo handig is?)
- Andere opties?

Ik heb uiteraard reeds gegoogled op "Friends relations database" en dergelijke, maar het enige wat ik vind zijn mensen die vragen hoe ze moeten uitnormaliseren.

Ik luister graag naar jullie input!

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Als je gewoon aanhoudt dat (bijv.) het laagste ID altijd in kolom A staat en het andere ID in kolom B heb je in ieder geval al een conventie om ze niet dubbel op te hoeven slaan ("omgekeerd" zoals je zegt).

Maar als ik jou markeer als vriend, ben je dan automatisch ook mijn vriend? Als dat niet zo is zul je namelijk wél "dubbel/omgekeerd" moeten gaan opslaan natuurlijk.

Verder is 't gewoon een kwestie van indexen zetten en een compound key gebruiken.

Overigens onze Search al eens gebruikt?

[ Voor 60% gewijzigd door RobIII op 14-04-2010 11:47 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Tharulerz
  • Registratie: April 2009
  • Laatst online: 10-04 05:16
Een friendsrelation is altijd in 2 richtingen ja.

Als A->B bestaat dan bestaan B->A ook.

Ik kijk ondertussen even door de search...

Edit: Momenteel staat er een UNIQUE over de combinatie A,B

[ Voor 18% gewijzigd door Tharulerz op 14-04-2010 11:49 ]


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Tharulerz schreef op woensdag 14 april 2010 @ 11:49:
Edit: Momenteel staat er een UNIQUE over de combinatie A,B
Nou, dan ben je er als je aanhoudt dat A altijd kleiner (of groter, wat jij wil) moet zijn dan B.
Zet een trigger op die voorwaarde (of hell, draai een cronjob die zo nu en dan de tabel naloopt en A<>B swapt of verwijdert waar nodig) en het is klaar :Y)

[ Voor 22% gewijzigd door RobIII op 14-04-2010 11:52 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Tharulerz
  • Registratie: April 2009
  • Laatst online: 10-04 05:16
Heb eens gekeken naar die Triggers maar dat lijkt me qua performance minder snel te zijn als een cron job.

Ik geraak enkel niet uit mijn delete query.

Als ik volgende select heb:

SELECT * from friends as a WHERE user IN (SELECT friend FROM friends as b WHERE user = a.friend) AND user < friend

Krijg ik alle records terug die ik wil deleten. Hoe maak ik hier nu een delete van? Alle pogingen die ik gedaan heb geven errors op aliasen en zo verder...

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Tharulerz schreef op woensdag 14 april 2010 @ 12:56:
Heb eens gekeken naar die Triggers maar dat lijkt me qua performance minder snel te zijn als een cron job.
Een trigger is alleen "duur" bij een insert (en define "duur").
Tharulerz schreef op woensdag 14 april 2010 @ 12:56:
Krijg ik alle records terug die ik wil deleten. Hoe maak ik hier nu een delete van? Alle pogingen die ik gedaan heb geven errors op aliasen en zo verder...
:?
Eerst voer je swaps uit waar nodig:
SQL:
1
2
3
INSERT INTO `vriendentabel` `v` (`user`, `friend`) VALUES (`t`.`friend`, `t`.`user`)
  SELECT `t`.`friend`, `t`.`user`
  FROM `vriendentabel` `t` WHERE `t`.`user` > `t`.`friend`

Daarna ruim je oude meuk op:
SQL:
1
Delete from `vriendentabel` where `user` >= `friend`

Dan zet je de unique en een trigger* die je voorwaardes voortaan controleert (dus A<B) et voila.
* Of schedule je een cronjob...

Als je gekozen hebt voor userid altijd kleiner dan friendid that is. De >= mikt meteen users die zichzelf bevriend hebben eruit :+

Heb je eenmalig deze actie (swappen, deleten) uitgevoerd en je software is in orde of je hebt een trigger dan hoef je dat natuurlijk daarna nooit meer te doen.

[ Voor 32% gewijzigd door RobIII op 14-04-2010 13:08 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Tharulerz
  • Registratie: April 2009
  • Laatst online: 10-04 05:16
Thanks! (Lelijke backticks trouwens! ugh!)

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Tharulerz schreef op woensdag 14 april 2010 @ 13:51:
(Lelijke backticks trouwens! ugh!)
user is een reserved word -> backticks.
En ik maak er gewoonte van alles te escapen (onder MSSQL met [ en ] en voor MySQL dus `); dan zit je altijd goed met reserved words die ze evt. gaan toevoegen, hoef je je nooit af te vragen of iets een reserved word is of niet en ben je consequent.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Tharulerz
  • Registratie: April 2009
  • Laatst online: 10-04 05:16
I know, maar dan nog liever enkel de reserved words backticken dan alles (reserved words ken je toch vanbuiten). En het is nu niet dat ze elke minor patch een reserved word toevoegen...

Acties:
  • 0 Henk 'm!

  • Wolfboy
  • Registratie: Januari 2001
  • Niet online

Wolfboy

ubi dubium ibi libertas

Tharulerz schreef op woensdag 14 april 2010 @ 14:11:
I know, maar dan nog liever enkel de reserved words backticken dan alles (reserved words ken je toch vanbuiten). En het is nu niet dat ze elke minor patch een reserved word toevoegen...
Of ANSI_QUOTES inschakelen, stuk fijner als je ooit eens een andere database wil gebruiken :)

Blog [Stackoverflow] [LinkedIn]

Pagina: 1