[{"data":1,"prerenderedAt":241},["ShallowReactive",2],{"i-lucide:menu":3,"i-lucide:arrow-up-right":8,"i-lucide:moon":10,"i-lucide:sun":12,"i-lucide:rss":14,"i-simple-icons:github":16,"i-simple-icons:linkedin":18,"post-\u002F2013\u002Fthe-database-from-inception-to-eol":21,"surround-\u002F2013\u002Fthe-database-from-inception-to-eol":228,"i-lucide:arrow-left":237,"i-lucide:arrow-right":239},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":7},0,24,false,"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 5h16M4 12h16M4 19h16\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":9},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 7h10v10M7 17L17 7\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":11},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":13},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"4\"\u002F>\u003Cpath d=\"M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32l1.41 1.41M2 12h2m16 0h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":15},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M4 11a9 9 0 0 1 9 9M4 4a16 16 0 0 1 16 16\"\u002F>\u003Ccircle cx=\"5\" cy=\"19\" r=\"1\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":17},"\u003Cpath fill=\"currentColor\" d=\"M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":19,"hidden":20},"\u003Cpath fill=\"currentColor\" d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037c-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85c3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.06 2.06 0 0 1-2.063-2.065a2.064 2.064 0 1 1 2.063 2.065m1.782 13.019H3.555V9h3.564zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0z\"\u002F>",true,{"id":22,"title":23,"body":24,"category":207,"comments":208,"date":209,"description":30,"excerpt":208,"extension":210,"image":208,"meta":211,"navigation":20,"path":212,"readingTime":213,"seo":214,"stem":215,"subtitle":208,"tags":216,"wordCount":226,"__hash__":227},"posts\u002F2013\u002Fthe-database-from-inception-to-eol.md","The Database: From Inception to EOL",{"type":25,"value":26,"toc":203},"minimark",[27,31,36,45,56,63,71,74,80,83,87,90,93,101,106,114,117,121,129,142,162,168,176,179,183,186,189,197,200],[28,29,30],"p",{},"This article outlines a workflow for creating, modifying and migrating the database schema (and data) with MySQL and PHP-orientated tools.",[32,33,35],"h1",{"id":34},"inception","Inception",[28,37,38,39,44],{},"I'm starting a new web application project, have talked to the client at length and have a decent understanding of the problem domain. Time to analyse and think about the data architecture of my application. I'll use the data modelling feature of ",[40,41,43],"a",{"href":42},"http:\u002F\u002Fwww.mysql.com\u002Fproducts\u002Fworkbench\u002F","MySQL Workbench",", a free tool for visual database design (and more).",[28,46,47,48,52,53],{},"With the help of my handy ",[40,49,51],{"href":50},"http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FEntity%E2%80%93relationship_model","ERD"," design tool it's easy to lay out the groundwork for my database schema. I'll create new tables and columns as I try to figure out the best architecture for my database. Foreign key relationships are easy to manage. Comments, notes and layers add additional information.",[54,55],"br",{},[28,57,58],{},[59,60],"img",{"alt":61,"src":62},"Database ERD","\u002Fcontent\u002F2013\u002F03\u002Fdb_erd.png",[28,64,65,66,70],{},"I can also insert some initial data to my tables, to be populated upon SQL import. An example for this would be the predefined entries of the ",[67,68,69],"code",{},"roles"," table. Triggers, stored procedures and other MySQL goodies are also manageable from the model.",[28,72,73],{},"When I'm satisfied with my initial design, I'll use the Export option and generate SQL from my model.",[28,75,76],{},[59,77],{"alt":78,"src":79},"Generate SQL","\u002Fcontent\u002F2013\u002F03\u002Fsql.png",[28,81,82],{},"The generated SQL file goes to my project folder along with the saved model (.mwb) file. I'll update them as I change the schema. The generated file goes into a new MySQL database as the initial dump.",[32,84,86],{"id":85},"initial-development","Initial Development",[28,88,89],{},"I now have a visual model of my database that I can easily update at will. Time to get started with the application code. I'll probably discover quite quickly that some table need modification or I'm missing an entity from the schema altogether. Time to open up the ERD model, add the missing object(s) and re-generate the SQL.",[28,91,92],{},"I've changed my model, but not the development database on my localhost. Since I almost always have my tables in InnoDB to support foreign keys, the dropping might be a bit... problematic. Try to drop the tables in the wrong order and you get a half-completed drop. I usually end up selecting all tables and the drop option three times in a row in phpMyAdmin.",[28,94,95,96,100],{},"What does a good developer do when he's forced to do something boring repeatedly? He automates it. I'm using ",[40,97,99],{"href":98},"https:\u002F\u002Fgithub.com\u002Fanroots\u002Fkohana-minion-importer","minion-importer"," to quickly drop the entire schema and rebuild it from the previously exported SQL dump.",[28,102,103],{},[59,104],{"alt":78,"src":105},"\u002Fcontent\u002F2013\u002F03\u002Fminion-importer.png",[28,107,108,109,113],{},"The dump contains some initial data rows, but it's always good to develop with a bigger example dataset. ",[40,110,112],{"href":111},"https:\u002F\u002Fgithub.com\u002Ffzaninotto\u002FFaker","fzaninotto\u002FFaker"," to the rescue. It's a PHP library that generates random test\u002Fsample data. Minion-importer has the skills to generate a number of sample rows for each table (8 in the above image).",[28,115,116],{},"I've changed the ERD model, exported it into SQL and rebuilt the development database to apply the change. This goes on for N iterations right up until initial deployment to Production.",[32,118,120],{"id":119},"production-maintenance","Production \u002F Maintenance",[28,122,123,124,128],{},"The production database is sacred. Thou ",[40,125,127],{"href":126},"http:\u002F\u002Fdevopsreactions.tumblr.com\u002Fpost\u002F40913477597\u002Fthat-moment-when-you-realize-youve-deleted-production","shalt not drop \u002F truncate \u002F destroy"," its records. Therefore, the previous approach of dropping the whole database and rebuilding it from scratch does not apply when you have to preserve client data.",[28,130,131,132,136,137,141],{},"Time to introduce ",[40,133,135],{"href":134},"http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSchema_migration","schema migrations",". I'll use ",[40,138,140],{"href":139},"http:\u002F\u002Fphinx.org","Phinx"," to describe my changes. Phinx is a relatively new PHP tool for reliably managing the state of the database. It takes more time to describe each change to the database (hence the reason why it's preferable to drop\u002Fbuild during development), but the added benefit are worth it:",[143,144,145,149,152,159],"ul",{},[146,147,148],"li",{},"Changes to the schema are described (in most cases) in a non-destructive manner (adding a column doesn't result in the loss of the table)",[146,150,151],{},"It's auditable - you always know the state and history of the database",[146,153,154,155],{},"It's automatable - run database migrations from your ",[40,156,158],{"href":157},"http:\u002F\u002Fwww.phing.info\u002F","build script",[146,160,161],{},"You can undo changes, effectively returning the database schema to an earlier state",[28,163,164],{},[59,165],{"alt":166,"src":167},"Migrations","\u002Fcontent\u002F2013\u002F03\u002Fmigrations.png",[28,169,170,171,175],{},"You might want to use migrations from the start when working in a team or wanting increased audit \u002F version history. I'm a lone developer for the moment and the changes I do before deployment don't need to be traceable in such detail... and there is always a VCS. You do ",[40,172,174],{"href":173},"http:\u002F\u002Fdevopsreactions.tumblr.com\u002Fpost\u002F36802261557\u002Fwhen-a-new-hire-asks-whether-he-should-use-git","use a VCS",", don't you?",[28,177,178],{},"I'll still be updating my Workbench model as I describe each change in my migrations. I want an up-to-date visual representation of my database and if I ever need to create a new instance of the system I can start from the SQL dump again.",[32,180,182],{"id":181},"end-of-life","End-of-life",[28,184,185],{},"All software systems die. Whether it's in twenty years (not many systems are coded so well) or in a next dozen-or-so months, it doesn't matter. A good developer plans for the death of his system from the start.",[28,187,188],{},"From the database perspective, two things are important: getting the data out (most likely importing it into the new, replacement system) and archiving the schema and data for backup \u002F archival purposes.",[28,190,191,192,196],{},"Getting the data out might be resolved with a simple CSV dump or your code might be good enough to provide an API for that (",[40,193,195],{"href":194},"http:\u002F\u002Fwaher.net\u002Farchives\u002F1158","read about API-centric design",", a rising trend in designing collaborative and accessible systems). Data archival is even simpler - gzip the database and press the big red button to permanently destroy the production database. Please be absolutely, positively, 101% sure the client and the company WANT this to happen and all valuable data has been extracted. There really should be cake and a big red button for such events. Let 'em die with honor.",[198,199],"hr",{},[28,201,202],{},"This is one of many ways to manage the life of a database. I find it to be fast and reliable, two reasons to keep at it. Please let me know what you think, any suggestions to improving the process are welcome. How do you manage the life of your databases?",{"title":204,"searchDepth":205,"depth":205,"links":206},"",2,[],"Software Development",null,"2013-03-10","md",{},"\u002F2013\u002Fthe-database-from-inception-to-eol","about 5 minutes",{"title":23,"description":30},"2013\u002Fthe-database-from-inception-to-eol",[217,218,219,220,221,222,223,224,225],"php","design","development","database","erd","architecture","mysql","versioning","workflow",965,"q1LIAw1z48BnekXlmows-B605B-d0MPAfKFk8h38TJA",[229,233],{"title":230,"path":231,"stem":232,"children":-1},"40 Ways To Lose Your Friend","\u002F2013\u002F40-ways-to-lose-your-friend","2013\u002F40-ways-to-lose-your-friend",{"title":234,"path":235,"stem":236,"children":-1},"Raising Awareness About IT Education In Estonia","\u002F2013\u002Fraising-awareness-about-it-education-in-estonia-summary-of-it-night-2013-roela","2013\u002Fraising-awareness-about-it-education-in-estonia-summary-of-it-night-2013-roela",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":238},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m12 19l-7-7l7-7m7 7H5\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":240},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 12h14m-7-7l7 7l-7 7\"\u002F>",1790886934082]