[MySQL] Best practices

Pagina: 1
Acties:
  • 172 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Topicstarter
In elke rdbms zijn er wel mogelijkheden om te optimaliseren op verschillende vlakken. Zowel op niveau van performance, beveiliging als schaalbaarheid. Nu heeft iedere rdbms zijn eigen best practices om tot bepaalde functionaliteit te komen.

Daarom wil ik dit topic starten om zo wat ervaringen te delen, best practices te delen maar zeker ook bepaalde pitfalls bespreken op niveau van MySQL als database. Zelf gebruik ik de InnoDB storage engine omdat ik consistentie hoog in het vaandel draag.

Natuurlijk trapt de TS zelf af met een aantal best practices die ik handig vind:

Security
MySQL kan default een aantal deuren open zetten voor eventuele ongewenste bezoekers; deze probeer ik te omzeilen door vlak na de installatie volgende commando's uit te voeren
SQL:
1
2
3
4
5
UPDATE user SET password = PASSWORD('rootpass') WHERE user = 'root'; -- password instellen voor de root user
UPDATE user SET password = PASSWORD('anon') WHERE user = ''; -- anonymous access securen
DELETE FROM user WHERE user = '' AND host = 'localhost'; --delete account with user privileges (windows)
SELECT host, user, password FROM user; -- overzichtje
FLUSH PRIVILEGES; -- tells server to create new ACL in memory

edit:
Wel even opletten dat je de PASSWORD() functie enkel gebruikt om de wachtwoorden van je mysql gebruikers te zetten


Performance
We moeten ervoor proberen te zorgen dat de index gebruikt wordt bij het query'en van de database, we kunnen dit testen door EXPLAIN <SQL> uit te voeren:
SQL:
1
2
... WHERE date >= 1994; -- MINDER
... WHERE date >= '1994-01-01'; -- BETER


Als we een literal value gebruiken in onze conditie, wordt de index misschien niet gebruikt:
SQL:
1
2
... WHERE id='18'; -- MINDER
...  WHERE id=18; -- BETER


Het is natuurlijk aan te raden om de output zover mogelijk te limiteren:
SQL:
1
2
SELECT * FROM table; -- MINDER
SELECT firstname, lastname FROM table; -- BETER


Korter, traffiek daalt wat, alle updates in 1x, flush van index gebeurt ook slechts 1x:
SQL:
1
2
3
4
5
6
7
8
9
INSERT INTO table(id, name) VALUES (1, 'fox'); INSERT INTO table(id, name) VALUES (2, 'abc'); -- MINDER
INSERT INTO table(id, name) VALUES (1, 'fox'),(2, 'abc'); -- BETER

-- INNODB:
BEGIN;
INSERT INTO table (id, name);
VALUES (1, 'fox');
VALUES (2, 'abc');
COMMIT;

Dit zijn er nog maar enkele en er zijn er vast nog een heel stuk meer. Ik denk zelfs dat enkele van deze voor discussie vatbaar zijn. Dit mag je aanhalen, maar probeer dan wel een nuttige toevoeging toe te brengen aan dit topic door ófwel een betere oplossing te suggereren ófwel nog een aantal andere tips of best practices aan te brengen.

Kom om met jullie best practices, pitfalls, optimalisaties, warnings, ... :Y)

Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 11-09 13:55
Bookmarked. Werk inmiddels een jaar of 5 met MySQL (vrijwel alleen MyIsam) maar heb het idee er nog lang niet alles uit te halen wat erin zit. Heb momenteel helaas geen best practices om te delen...

Acties:
  • 0 Henk 'm!

  • JeRa
  • Registratie: Juni 2003
  • Laatst online: 30-04 10:28

JeRa

Authentic

Waarschijnlijk ontzettend voor de hand liggend, maar zorg dat je alleen nuttige indices gebruikt in je tables en ANALYZE TABLE gebruikt om de cardinality voor die indices te updaten. De cardinality wordt geüpdatet en vanaf dat moment worden alle indices (behalve de PRIMARY KEY afaik) geschaald aan de hand van het aantal records. Insert je dus hetzelfde aantal records in een tabel als dat er op dat moment in zitten, dus je maakt de inhoud 2x zo groot, dan wordt de cardinality ook 2x zo groot geschat als je in de tussentijd geen ANALYZE TABLE hebt uitgevoerd. Indien mogelijk moet je dat dus zo laat mogelijk uitvoeren :)

ifconfig eth0 down


Acties:
  • 0 Henk 'm!

  • BHR
  • Registratie: Februari 2002
  • Laatst online: 04-09 20:24

BHR

-FoX- schreef op zaterdag 04 november 2006 @ 21:49:
...
Het is natuurlijk aan te raden om de output zover mogelijk te limiteren:
SQL:
1
2
SELECT * FROM table; -- MINDER
SELECT firstname, lastname FROM table; -- BETER
Ik gebruik altijd de bovenste, tenzij er een specieke reden is dat niet te doen; zoals wanneer de record lengte groot is (door gebruik van TEXT of BLOB) of bij een *zwaar* gebrek aan performance. Ik vind het namelijk belangrijker dat bv. wanneer je een kolom toevoegt aan de tabel, deze gelijk terugkomt in alle resultsets die op die tabel werken. Anders moet je bij veel gebruik van die tabel, heel veel queries bij langs om een kolom toe te voegen aan de sql statement.

In deze situatie vind ik gemak dus belangrijker dan performance.

No amount of key presses will shut off the Random Bug Generator


Acties:
  • 0 Henk 'm!

  • Paul
  • Registratie: September 2000
  • Laatst online: 20:09
Dat ligt er maar net aan wat je wilt doen. Maak je een overzichtslijst waarin alle gegevens uit de tabel moeten komen dan is het natuurlijk onzin om geen * te gebruiken.
Heb je echter uit de personen-tabel (met verder nog de straat, postcode, woonplaats, adres, leeftijd, telefoonnummer overdag, telefoonnummer 's avonds, mobiel, fax, email, bankrekeningnummer etc etc) alleen de voor- en achterna(a)m(en) nodig dan valt er op deze manier het een en ander aan geheugen- en bandbreedteverbruik te besparen, terwijl het niet eens in de catagorie premature optimization valt :) Maak je er een kolom bij (die je op datzelfde punt dus nodig hebt) moet je de code toch aanpassen en kun je net zo goed de select-statement uitbreiden.

[ Voor 31% gewijzigd door Paul op 05-11-2006 01:43 . Reden: Quote niet nodig ]

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


Acties:
  • 0 Henk 'm!

  • Paul C
  • Registratie: Juni 2002
  • Laatst online: 12-09 11:33
Ik heb nu een twee concrete vragen voor Best Practices:
- Hoe kun je het beste een datum en tijd opslaan in MySQL en wat zijn de voor en nadelen van verschillende methodes? Mogelijkheden zijn volgens mij INT, TIMESTAMP, DATETIME, DATE & TIME en ik gebruik tot nu toe altijd INT, maar volgens mij is TIMESTAMP beter?
- Hoe kun je het beste een IP opslaan in MySQL vanuit PHP? Ik gebruik nu altijd een INT en dan gebruik ik in PHP long2ip(); en ip2long();, maar kan dit misschien beter?

Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 00:05

MBV

nee. Met een timestamp sla je het tijdstip op waarop de rij is gewijzigd. Je kan dus het beste DATETIME gebruiken, dan kan je bijvoorbeeld ook selecteren op maand, of je datum formatteren in je select. Als je bijvoorbeeld een Unix Timestamp en de 'standaard' tijdweergave nodig hebt, kan je
SQL:
1
2
SELECT UNIX_TIMESTAMP(time) unix_time, time
FROM ...

Met inserten kan je FROM_UNIXTIME() gebruiken :)

De 2e zou ik niet weten.

Acties:
  • 0 Henk 'm!

Verwijderd

MBV schreef op zondag 05 november 2006 @ 15:57:
nee. Met een timestamp sla je het tijdstip op waarop de rij is gewijzigd. Je kan dus het beste DATETIME gebruiken, dan kan je bijvoorbeeld ook selecteren op maand, of je datum formatteren in je select. Als je bijvoorbeeld een Unix Timestamp en de 'standaard' tijdweergave nodig hebt, kan je
SQL:
1
2
SELECT UNIX_TIMESTAMP(time) unix_time, time
FROM ...


De 2e zou ik niet weten.
ik sla een normaal (IPv4) adres gewoon altijd als VARCHAR van 15 chars op. Voor opslag/tonen werkt dat prima, alleen is het traag als je er in zoekt.

[ Voor 6% gewijzigd door Verwijderd op 05-11-2006 16:25 ]


Acties:
  • 0 Henk 'm!

  • Theuno
  • Registratie: Juni 2001
  • Laatst online: 00:21

Theuno

Da Devil Crew

Verwijderd schreef op zondag 05 november 2006 @ 16:25:
[...]


ik sla een normaal (IPv4) adres gewoon altijd als VARCHAR van 15 chars op. Voor opslag/tonen werkt dat prima, alleen is het traag als je er in zoekt.
Als je het dan inderdaad best-practice wil doen moet je het niet in een VARCHAR opslaan, en is de INT oplossing het netst vanuit de database gezien.
Voor het gemak is het een ander geval, en moet je het dus even bekijken met hoevaak je het gaat gebruiken. Per geval kan dit dus anders zijn...

Theuno - Da Devil Crew - Een programmeur is iemand die koffie omzet in software...
Nu nog betere koffie...


Acties:
  • 0 Henk 'm!

  • Raynman
  • Registratie: Augustus 2004
  • Laatst online: 00:29
BHR schreef op zaterdag 04 november 2006 @ 23:10:
[...]

Ik gebruik altijd de bovenste, tenzij er een specieke reden is dat niet te doen; zoals wanneer de record lengte groot is (door gebruik van TEXT of BLOB) of bij een *zwaar* gebrek aan performance. Ik vind het namelijk belangrijker dat bv. wanneer je een kolom toevoegt aan de tabel, deze gelijk terugkomt in alle resultsets die op die tabel werken. Anders moet je bij veel gebruik van die tabel, heel veel queries bij langs om een kolom toe te voegen aan de sql statement.

In deze situatie vind ik gemak dus belangrijker dan performance.
Als je een kolom toevoegt die je in bepaalde resultsets nodig hebt, zul je bij de verwerking van die resultset toch ook dingen moeten veranderen/toevoegen om iets met die nieuwe informatie te doen? Dan loop je ze dus eigenlijk al langs en kun je ook meteen de query veranderen. Ik zie niet welk gemak SELECT * hier oplevert.

Acties:
  • 0 Henk 'm!

  • jopiek
  • Registratie: September 2000
  • Laatst online: 08-09 07:26

jopiek

Tja... 'ns ff denken.

Theuno schreef op zondag 05 november 2006 @ 17:25:
[...]


Als je het dan inderdaad best-practice wil doen moet je het niet in een VARCHAR opslaan, en is de INT oplossing het netst vanuit de database gezien.
Voor het gemak is het een ander geval, en moet je het dus even bekijken met hoevaak je het gaat gebruiken. Per geval kan dit dus anders zijn...
Op zich ben ik het er mee eens, maar wat is "best practise": wat is leidend, de regels voor RDB's of geheugengebruik. Ik zou ws. een leerling die een IP in een integer zet op z'n duvel gevel voor het produceren van een onverantwoord database ontwerp. Overigens is een hex reeks van 4 karakters voor storage ws. de zuinigste oplossing en ook nog eens mooier ivm constraints.

[ Voor 8% gewijzigd door jopiek op 05-11-2006 17:36 ]

Cogito Ergo Credo


Acties:
  • 0 Henk 'm!

  • Paul
  • Registratie: September 2000
  • Laatst online: 20:09
Waarom? Een ip-adres _IS_ een 32bit unsigned integer. Dat mensen "3232235521" te lastig vinden en liever de representatie "192.168.0.1" zien, wil niet zeggen dat het datatype ineens een string is.

Of geef je leerlingen ook op hun donder als ze een datumveld gebruiken ipv een varchar waar ze "zondag 5 november 2006" inzetten?

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


Acties:
  • 0 Henk 'm!

  • jopiek
  • Registratie: September 2000
  • Laatst online: 08-09 07:26

jopiek

Tja... 'ns ff denken.

Paul Nieuwkamp schreef op zondag 05 november 2006 @ 17:36:
Waarom? Een ip-adres _IS_ een 32bit unsigned integer. Dat mensen "3232235521" te lastig vinden en liever de representatie "192.168.0.1" zien, wil niet zeggen dat het datatype ineens een string is.

Of geef je leerlingen ook op hun donder als ze een datumveld gebruiken ipv een varchar waar ze "zondag 5 november 2006" inzetten?
wel je hebt idd gelijk, ik had dat even over het hoofd gezien (zie idd: http://nl.wikipedia.org/wiki/IPv4)

Cogito Ergo Credo


Acties:
  • 0 Henk 'm!

  • eghie
  • Registratie: Februari 2002
  • Niet online

eghie

Spoken words!

jopiek schreef op zondag 05 november 2006 @ 17:31:
[...]


Op zich ben ik het er mee eens, maar wat is "best practise": wat is leidend, de regels voor RDB's of geheugengebruik. Ik zou ws. een leerling die een IP in een integer zet op z'n duvel gevel voor het produceren van een onverantwoord database ontwerp. Overigens is een hex reeks van 4 karakters voor storage ws. de zuinigste oplossing en ook nog eens mooier ivm constraints.
Als het performance technisch beter is om het in een INT op te slaan, zou ik dat beter vinden, mits het dus een goede reden heeft. Performance technisch is een INT ook beter dan een varchar, want INT's zijn voor opslag beter, maar je kunt er ook sneller op zoeken. Ik weet niet hoe hex tegenover int presteerd.

Als je veel dezelfde selects moet doen binnen relationele tabellen, maar die wel bestaan uit verschillende applicatie sessies (bijvoorbeeld verschillende mensen die je PHP applicatie aanroepen), kun je denk ik beter een view gebruiken. Want volgens mij kan MySQL die views beter cachen dan elke keer een losse SQL query. Of zie ik dit misschien verkeerd? Nu heb ik het over MySQL 5 die dus views ondersteund.

Misschien wat voor de hand liggend, maar wordt nog niet altijd gedaan, is dat je voor elke applicatie die met MySQL moet verbinden een aparte gebruiker aan maakt. Misschien is het daarbij ook nog wel handig dat er een gebruiker is om je database te doorzoeken, maar niet de rechten heeft om dingen te verwijderen bijvoorbeeld. Gezien een best practise op beveiligings gebied is om elk niveau binnen je applicatie zo veel mogelijk probeerd te beveiligen, moet je natuurlijk ook je database zoveel mogelijk beveiligen.

[ Voor 17% gewijzigd door eghie op 05-11-2006 18:01 ]


Acties:
  • 0 Henk 'm!

  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
Wat ook een best practice is (maar mischien niet helemaal de best practice die mensen hier willen horen):

Probeer ook eens een andere DB dan MySQL

Afhankelijk van jouw applicatie kan dat heel veel schelen. In de praktijk kom ik eigenlijk te veel mensen tegen die zich helemaal blind staren op MySQL. Als ik dan uitleg dat er nog andere (open source & gratis!) databases bestaan, staat men mij met open mond aan te staren.

Recentelijk bleek bijvoorbeeld dat tweakers heel wat beter zou draaien op PostgreSQL dan op MySQL (zie artikel FP).

Dit is niet om MySQL af te kraken, maar gewoon om mensen er op te wijzen eens te benchmarken voor hun applicatie wat nu het beste performed ipv altijd maar blind meteen voor MySQL te kiezen.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 00:05

MBV

dat lijkt mij een heel verstandige, alleen heet dit het MySQL best practices topic, niet het OSS DB topic ;).
Veel mensen zitten opgescheept met 'legacy' troep die overschakelen naar Postgre onmogelijk maakt. Als het simpel een veldje omzetten was geweest voor de FP, hadden ze dat immers toch wel omgezet? Het was toch sneller?
Daarnaast: als je toch al voor pak-em-beet Joomla een MySQL database hebt draaien, kan je toch net zo goed je andere apps ook met MySQL laten draaien? de performance zal daar alleen beter van worden, ivm. minder geheugenverbruik.

Maar het is zeker een aanrader om het in een nieuwe omgeving uit te testen, en je app zo te schrijven dat je snel kan overschakelen. Query's bij elkaar gooien enzo. Doe ik ook altijd O-) En al mijn voorgangers ook... :'( ach ja, in ieder geval is alles al omgezet naar AdoDB, dus omzetten wordt iets makkelijker. Nu nog alle 5 locaties met configuraties vinden... :(

[ Voor 24% gewijzigd door MBV op 05-11-2006 22:01 ]


Acties:
  • 0 Henk 'm!

  • orf
  • Registratie: Augustus 2005
  • Laatst online: 23:38

orf

Voor IP adressen zijn er twee mooie functies:


INET_ATON(expr)

Given the dotted-quad representation of a network address as a string, returns an integer that represents the numeric value of the address. Addresses may be 4- or 8-byte addresses.

SQL:
1
2
mysql> SELECT INET_ATON('209.207.224.40');
        -> 3520061480


INET_NTOA(expr)

Given a numeric network address (4 or 8 byte), returns the dotted-quad representation of the address as a string.

SQL:
1
2
mysql> SELECT INET_NTOA(3520061480);
        -> '209.207.224.40'


Een leuke voor counts:

FOUND_ROWS()

A SELECT statement may include a LIMIT clause to restrict the number of rows the server returns to the client. In some cases, it is desirable to know how many rows the statement would have returned without the LIMIT, but without running the statement again. To obtain this row count, include a SQL_CALC_FOUND_ROWS option in the SELECT statement, and then invoke FOUND_ROWS() afterward:

SQL:
1
2
3
mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
    -> WHERE id > 100 LIMIT 10;
mysql> SELECT FOUND_ROWS();

Acties:
  • 0 Henk 'm!

  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
MBV schreef op zondag 05 november 2006 @ 21:35:
dat lijkt mij een heel verstandige, alleen heet dit het MySQL best practices topic, niet het OSS DB topic ;).
Veel mensen zitten opgescheept met 'legacy' troep die overschakelen naar Postgre onmogelijk maakt. Als het simpel een veldje omzetten was geweest voor de FP, hadden ze dat immers toch wel omgezet? Het was toch sneller?
Inderdaad, dat was ook een beetje de strekking van het FP artikel.

Aan je software interface ligt het niet. Om van DB te wisselen is het inderdaad niet meer werk dan een veldje omzetten (komt er op neer dat je alleen een andere DB driver naam op geeft).

Het grootste struikelblok is dat je altijd met de vervelende keuze zit:

Gebruik ik een speciale MySQL functie/mogelijkheid/whatever, of ga ik voor 100% standaard SQL. Met 100% standaard SQL zullen je queries zeer waarschijnlijk op elke DB draaien, maar laat je wellicht mogelijkheden van jouw specificieke DB liggen. Zelfde geldt natuurlijk al je begint met PostgreSQL.

Ik weet niet of je het al een "best practice" mag noemen, maar het is ook nog een optie om:

Geen handmatige SQL te schrijven

Als je al je data ophaalt via een hogere abstractie laag ( het O/R mapper principe), dan genereerd de middleware layer de SQL voor jou. De betere O/R mappers kunnen hoog geoptimaliseerde SQL genereren, en kunnen dat vanuit de zelfde high-level abstractie voor zeer diverse DB's doen.

Dit is direct te vergelijken met het compileren van bv C++. De compiler genereerd uit dezelfde C++ source code assembly voor totaal verschillende CPU's. Deze assembly is ondertussen meer geoptimaliseerd dat jij handmatig nog voor elkaar kan krijgen.

Voordeel is dat jij daadwerkelijk zonder problemen van DB kunt wisselen. Natuurlijk kun je deze voordelen alleen plukken bij nieuwe projecten die 100% de O/R mapper techniek gebruiken.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


Acties:
  • 0 Henk 'm!

  • Paul C
  • Registratie: Juni 2002
  • Laatst online: 12-09 11:33
MBV schreef op zondag 05 november 2006 @ 15:57:
nee. Met een timestamp sla je het tijdstip op waarop de rij is gewijzigd. Je kan dus het beste DATETIME gebruiken, dan kan je bijvoorbeeld ook selecteren op maand, of je datum formatteren in je select. Als je bijvoorbeeld een Unix Timestamp en de 'standaard' tijdweergave nodig hebt, kan je
SQL:
1
2
SELECT UNIX_TIMESTAMP(time) unix_time, time
FROM ...

Met inserten kan je FROM_UNIXTIME() gebruiken :)

De 2e zou ik niet weten.
Owkay, dat helpt en is een heel sterk argument om voor DATETIME te kiezen. Echter zat ik net ff wat te lezen en toen kwam ik ook een sterk argument tegen om voor INT te kiezen. INT is namelijk 4bytes groot terwijl DATETIME 8bytes groot is. Als je zeer veer tijden op moet slaan die niet buiten het bereik van een UNIX_TIMESTAMP vallen, dan is het dus ook het overwegen waard om dit met een INT te doen, afhankelijk van hoe je wilt selecten. Het is natuurlijk netter om DATETIME te gebruiken aangezien deze voor dit doel ontworpen is. Als tussen oplossing zou je ook nog voor een DATE en een TIME field kunnen kiezen, deze beslaan allebei 3bytes en komen samen dus op 6bytes uit.

Acties:
  • 0 Henk 'm!

Verwijderd

Paul Nieuwkamp schreef op zondag 05 november 2006 @ 01:42:
....
Heb je echter uit de personen-tabel (met verder nog de straat, postcode, woonplaats, adres, leeftijd, telefoonnummer overdag, telefoonnummer 's avonds, mobiel, fax, email, bankrekeningnummer etc etc) alleen de voor- en achterna(a)m(en) nodig dan valt er op deze manier het een en ander aan geheugen- en bandbreedteverbruik te besparen......
Geheugen... ok, maar bandbreedte?? Deze queries worden toch server side afgehandeld om vervolgens door een aldaar geinterpreteerd te worden en vertaald te worden naar een bepaalde HTML output (door in de meeste gevallen PHP oid)? Ik ben zelf vaak ook door luiigheid een beetje van het type SELECT *, zeker als ik >60% van de columns nodig heb. Ik vind mn queries namelijk een stuk minder overzichtelijk als ik van een tabel met 20 velden alle namen benoem t.o.v. SELECT *.

Ik vroeg me daarom ook af of geheugengebruik echt het enige probleem is. Voor de sites waar ik MySQL voor gebruik is snelheid vaak geen probleem, weinig gebruikers, huis- tuin- en keukengebruik zeg maar.... Iemand nog argumenten die mij doen besluiten netter om te springen met de resources van mijn hoster(s)?

Acties:
  • 0 Henk 'm!

  • Paul
  • Registratie: September 2000
  • Laatst online: 20:09
Verwijderd schreef op maandag 06 november 2006 @ 10:11:
[...]

Geheugen... ok, maar bandbreedte??
Niet iedere MySQL-daemon draait op dezelfde bak als de MySQL-client (PHP of anders) ;)
Dan kan het nog zijn dat er en gigabitlijn ligt tussen server en client, maar toch :)

Beetje extreem voorbeeld: in sommige applicaties die ik moet onderhouden (of eigenlijk, de meeste :'( ) worden nog dBase-"databases" gebruikt. Als je daar een filter durft te zetten of een browselijst opvraagt staat je 100mbit lijn tussen de client en de server (lees: fileserver :X ) vaak een paar seconden op een procent of 50, 60, en dat voor een DB van 4 MB.
Dat ligt in dit geval dus meer aan het gebruikte RDBMS en de Delphi DB-aware controls, maar het blijft het in de DB-laag inefficient omgaan met je bandbreedte.

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


Acties:
  • 0 Henk 'm!

  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Topicstarter
Het is blijkbaar niet mogelijk om 2 TIMESTAMP columns te hebben in 1 tabel, die zichzelf automatisch updated; als voorbeeld 2 timestamp kolommen "created" en "modified".

code:
1
2
3
4
5
6
7
CREATE TABLE tstable (
  id              INTEGER       NOT NULL AUTO_INCREMENT,
  name            VARCHAR(25)   NOT NULL,
  created         TIMESTAMP     DEFAULT NOT NULL CURRENT_TIMESTAMP,
  modified        TIMESTAMP     DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY(id)
) TYPE=InnoDB;

Dit is dus niet toegelaten. Kent iemand een best-practice om hiermee om te gaan? (buiten het feit dit door de applicatie te laten regelen)

Acties:
  • 0 Henk 'm!

  • Paul
  • Registratie: September 2000
  • Laatst online: 20:09
Als je bij een insert of update geen waarde meegeeft voor je timestamp-field wordt er automatisch de huidige tijd ingezet. Ik denk dat het daarmee samenhangt.

Ik zou dus een datetime-field gebruiken voor de create-date :)

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Dit staat overigens in TIMESTAMP Properties >= 4.1, een stukje documentatie dat niet echt een genot is om door te lezen... :X

{signature}


Acties:
  • 0 Henk 'm!

  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Topicstarter
Paul Nieuwkamp schreef op maandag 06 november 2006 @ 15:59:
Als je bij een insert of update geen waarde meegeeft voor je timestamp-field wordt er automatisch de huidige tijd ingezet. Ik denk dat het daarmee samenhangt.

Ik zou dus een datetime-field gebruiken voor de create-date :)
En hoe laat je deze dan defaulten naar creatie datum?

Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 00:05

MBV

bij de insert? :P Kan je niet als default-value de NOW() functie gebruiken? Dan ben je er toch al?

En Timestamp is idd een ramp om te begrijpen :(

Acties:
  • 0 Henk 'm!

  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Topicstarter
Hier nog een aantal (84) tips: MySQL Performance Tips

Export data to XML
Manier om data te converteren naar een XML representatie:
code:
1
mysqldump -q -X -t <database> <table>

Een extra parameter kan toegevoegd worden om een where conditie uit te drukken, vb:
code:
1
-w "name like 'test%'"

om alle (test)users in XML vorm weer te geven...

[ Voor 57% gewijzigd door -FoX- op 20-11-2006 12:20 ]


Acties:
  • 0 Henk 'm!

  • sig69
  • Registratie: Mei 2002
  • Laatst online: 00:34
Wat is het probleem met een Timestamp dan? Het is heel simpel: het eerste Timestamp veld wordt bij elke update automatisch bijgewerkt, en that's it. Voor een create time zou je dus sowieso al niet moeten willen dat dit gebeurd. Gebruik dan een DateTime met als default de huidige tijd en stuur 'm niet mee in je create query.

Roomba E5 te koop


Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 22:22
sig69 schreef op maandag 20 november 2006 @ 12:21:
Wat is het probleem met een Timestamp dan? Het is heel simpel: het eerste Timestamp veld wordt bij elke update automatisch bijgewerkt, en that's it. Voor een create time zou je dus sowieso al niet moeten willen dat dit gebeurd. Gebruik dan een DateTime met als default de huidige tijd en stuur 'm niet mee in je create query.
Er staat me vaag iets bij over dat MySQL NOW() niet accepteerd als default waarde, maar could be wrong there. Sowieso is het natuurlijk geen probleem die in je insert query te stoppen :)

//edit
Net even getest, maar met NOW() als default waarde krijg ik een #1067 - Invalid default value for 'tabelnaam' error, dus of ik mis iets of het kan inderdaad niet :)

Nog een wat algemenere obvious best practice: wees consistent met je naamgeving. Het wordt daarnaast niet zelden zeer gewaardeerd als je tabelnamen prefixed met een default waarde afhankelijk van het pakket (de tabelnamen van frogblog bijvoorbeeld heten allemaal fb_tabelNaam). Ook ID's en naam-velden hebben hier baat bij. Zelf gebruik ik eerste-letter-pakket eerste-letter-tabel _ waarde, het ID van de fb_comments table bijvoorbeeld zal dus altijd fc_ID heten. Heb eens in een applicatie van iemand anders een half uur lopen troubleshooten tot ik erachter kwam dat ID soms met een hoofdletter en soms met kleine letters geschreven was...

Overigens ga ik er vanuit dat er mensen zijn die mijn naamgevingsregels stom vinden, dit is hoe ik het mezelf aangeleerd heb maar ook vooral hoe het mij aangeleerd is door anderen, en de reden voor bepaalde conventies is niet altijd even duidelijk. Dit doet er IMHO ook niet echt toe, zolang je maar een vaste set naamgevingsregels aanhoudt en iedereen schopt die ze overtreed :)

[ Voor 5% gewijzigd door FragFrog op 20-11-2006 14:30 ]

[ Site ] [ twitch ] [ jijbuis ]

Pagina: 1