<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Programmer&#039;s Notes &#187; modelling</title>
	<atom:link href="http://programmersnotes.info/tag/modelling/feed/" rel="self" type="application/rss+xml" />
	<link>http://programmersnotes.info</link>
	<description>Notes on the web-development and artificial intelligence.</description>
	<lastBuildDate>Mon, 18 Jul 2011 13:20:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Database structure and filtering approach. SMS Notification system.</title>
		<link>http://programmersnotes.info/2010/03/19/database-sms-notification/</link>
		<comments>http://programmersnotes.info/2010/03/19/database-sms-notification/#comments</comments>
		<pubDate>Fri, 19 Mar 2010 06:00:38 +0000</pubDate>
		<dc:creator>Konstantin Mirin</dc:creator>
				<category><![CDATA[DB Design]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[database design]]></category>
		<category><![CDATA[modelling]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[sms-notify]]></category>
		<category><![CDATA[UML]]></category>

		<guid isPermaLink="false">http://programmersnotes.info/?p=351</guid>
		<description><![CDATA[The database structure In the previous post I outlined the system&#8217;s specs and use cases. We also selected the primary use case we should start from – that is filtering screen. The complexity with DB design here is that we want maximum flexibility on the one hand and we don&#8217;t want to lose much in [...]


No related posts.

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<h2><a name="dbstruct">The database structure</a></h2>
<p>In the <a href="http://programmersnotes.info/2010/03/18/requirements-use-cases-sms-notification/">previous post</a> I outlined the system&#8217;s specs and use cases. We also selected the primary use case we should start from – that is <a href="http://programmersnotes.info/2010/03/18/requirements-use-cases-sms-notification/#groupadmin">filtering screen</a>.</p>
<p><span id="more-351"></span></p>
<p>The complexity with DB design here is that we want maximum flexibility on the one hand and we don&#8217;t want to lose much in performance on the other hand.<br />
Let&#8217;s recap what data about student we should store:</p>
<ol>
<li>Phone</li>
<li>Password</li>
<li>Email</li>
<li>ICQ</li>
<li>Name</li>
<li>Surname</li>
<li>Patronymic</li>
<li>Gender</li>
<li>Birthday</li>
<li>Faculty</li>
<li>Course</li>
<li>Group</li>
<li>Clubs</li>
<li>Tags</li>
<li>OK to send SMS (true/false)</li>
</ol>
<p>Items 1-9 and #15 are scalar values and can be easily stored in User table as fields of the correspondent type. While Faculty, Course, Group and Clubs are either N-M (Clubs) or 1-N relations. So obvious way to handle them is to create tables and cross-table for N-M relation. Tags can be also represented as N-M relation.<br />
It seems OK until we don&#8217;t want to extend the system by adding some more fields. But even without extensibility in mind, we should create 3 separate tables (for courses, faculties and clubs). However if we look closer at these, we&#8217;ll see that all of them are kind of groups and we can create a kind of hierarchy:</p>
<ul>
<li>University
<ul>
<li>Faculty
<ul>
<li>Course
<ul>
<li>Group</li>
</ul>
</li>
</ul>
</li>
<li>Club
<ul>
<li>Section</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>So we can consider everything to be group. With this approach we also store information about relations between these groups.<br />
With such approach we can add more types of groups in the future if needed. Or this solution can be ported to another domain model (e.g. school or business organization) without changes in the structure. We should only define, which groups are required for user. In this case Faculty, course and group are required. However, knowing the group, we can get both course and faculty. But I&#8217;m not sure if that is a good idea because this way we&#8217;ll have to make several queries to the DB in order to get faculty instead of one.<br />
Here&#8217;s the DB scheme we came up with:</p>
<div id="attachment_360" class="wp-caption aligncenter" style="width: 566px"><a href="http://programmersnotes.info/wp-content/uploads/2010/03/db.png"><img src="http://programmersnotes.info/wp-content/uploads/2010/03/db.png" alt="Database design" title="Database design" width="556" height="349" class="size-full wp-image-360" /></a><p class="wp-caption-text">Database design</p></div>
<h2><a name="filtering">Filtering it</a></h2>
<p>Let&#8217;s try to compose some simple queries to test if our DB can cope with them.</p>
<ol>
<li>Let&#8217;s get all male users who&#8217;re elder than 18:
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">SELECT</span> * <span class="kw1">FROM</span> User <span class="kw1">WHERE</span> gender=<span class="st0">&#8216;male&#8217;</span> <span class="kw1">AND</span> birthday &lt;= <span class="st0">&#8217;1992-03-19 23:59:59&#8242;</span></div>
</li>
</ol>
</div>
<p>Date for the birthday is set to the 18 years back from now. Everyone who was born before or on 19 of March 1992 will fall into the condition. And gender is obvious.</li>
<li>Let&#8217;s try to get all male that have first names starting with &#8216;K&#8217; and who study on the first or second course:
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">SELECT</span> u.* <span class="kw1">FROM</span> User u <span class="kw1">INNER</span> <span class="kw1">JOIN</span> UserGroup ug <span class="kw1">ON</span> u.userID=ug.userID <span class="kw1">WHERE</span> u.gender=<span class="st0">&#8216;male&#8217;</span> <span class="kw1">AND</span> u.name <span class="kw1">LIKE</span> <span class="st0">&#8216;K%&#8217;</span> <span class="kw1">AND</span> ug.groupID <span class="kw1">IN</span> <span class="br0">&#40;</span><span class="nu0">5</span>,<span class="nu0">6</span><span class="br0">&#41;</span></div>
</li>
</ol>
</div>
<p>Suppose that in Group table we have groups for the first course and second course and they have Ids 5 and 6 respectively.</li>
<li>Let&#8217;s try to search for all who is on the 3rd course and is also in Geeks&#8217; Club:
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">SELECT</span> u.* <span class="kw1">FROM</span> User u <span class="kw1">INNER</span> <span class="kw1">JOIN</span> UserGroup ug <span class="kw1">ON</span> u.userID=ug.userID <span class="kw1">WHERE</span> ug.groupID <span class="kw1">IN</span> <span class="br0">&#40;</span><span class="nu0">7</span>, <span class="nu0">15</span><span class="br0">&#41;</span></div>
</li>
</ol>
</div>
<p>7 is ID of the group “3rd course” and 15 is ID of the group “Geeks&#8217; Club”.<br />
We have the problem with the last query <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  It will find all users who either studies on the 3rd course or attends Geeks&#8217; Club. However we need 3rd course and Geeks&#8217; club.<br />
There are two possible solutions here. One is SQL-based, another is PHP-based.</p>
<ol>
<li>1.SQL-based:
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">SELECT</span> * <span class="kw1">FROM</span> User <span class="kw1">WHERE</span> userID <span class="kw1">IN</span> <span class="br0">&#40;</span><span class="kw1">SELECT</span> userID <span class="kw1">FROM</span> UserGroup <span class="kw1">WHERE</span> userID <span class="kw1">IN</span><span class="br0">&#40;</span><span class="kw1">SELECT</span> userID <span class="kw1">FROM</span> UserGroup <span class="kw1">WHERE</span> groupID=<span class="nu0">15</span><span class="br0">&#41;</span> <span class="kw1">AND</span> groupID=<span class="nu0">7</span><span class="br0">&#41;</span></div>
</li>
</ol>
</div>
<p>Here we select users who have group=15. Then from these users we select the ones who have group=7 as well, and finally we select user records that correspond the userIDs found.<br />
I think, the variant with INNER JOIN is also possible here (at least, joining results of the groups filtering instead of sub-querying). It just takes some time to figure it out and it has to deal more with optimization than with the principle of filtering.<br />
Anyway, the more groups we have here, the more complex this query becomes.<br />
<strong>UPDATE:</strong> <a href="http://www.sitepoint.com/forums/showthread.php?p=4542692">Here</a> I&#8217;ve been advised to use the following query which is more simple and efficient:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">SELECT</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; u.*</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">FROM</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; USER u</div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">INNER</span> <span class="kw1">JOIN</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; UserGroup ug1</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ON</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; u.id = ug1.userID <span class="kw1">AND</span> ug1.groupID=<span class="nu0">7</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">INNER</span> <span class="kw1">JOIN</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; UserGroup ug2</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ON</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; u.id = ug2.userID <span class="kw1">AND</span> ug2.groupID=<span class="nu0">15</span></div>
</li>
</ol>
</div>
<p>I think this is the best way of making such queries. Great thanks to <strong>ScallioXTX</strong></li>
<li>PHP-based. Basically, the principle is the same:
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="re0">$group7</span> = getUsersForGroup<span class="br0">&#40;</span><span class="nu0">7</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$group15</span> = getUsersForGroup<span class="br0">&#40;</span><span class="nu0">15</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$userIDs</span> = <a href="http://www.php.net/array_intersect"><span class="kw3">array_intersect</span></a><span class="br0">&#40;</span><span class="re0">$group7</span>, <span class="re0">$group15</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$users</span> = getUsersByIDs<span class="br0">&#40;</span><span class="re0">$userIDs</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>getUsersForGroup actually executes the query:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">SELECT</span> userID <span class="kw1">FROM</span> UserGroup <span class="kw1">WHERE</span> groupID=<span class="br0">&#91;</span><span class="kw1">GROUP</span><span class="br0">&#93;</span></div>
</li>
</ol>
</div>
<p>getUsersByID executes the following query:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">SELECT</span> * <span class="kw1">FROM</span> User <span class="kw1">WHERE</span> userID <span class="kw1">IN</span> <span class="br0">&#40;</span><span class="br0">&#91;</span>ids<span class="br0">&#93;</span><span class="br0">&#41;</span></div>
</li>
</ol>
</div>
<p>array_intersect is a PHP function that returns the values present in all given arrays, returns the intersection of sets.<br />
For example, if we give it 3 arrays:<br />
(1, 5, 8, 15)<br />
(5, 8, 15, 19)<br />
(1, 5, 15, 25)<br />
it will return (5, 15).<br />
In this case we execute several little queries instead of one big. In MySQL this often gives benefits in performance.</li>
</ol>
</li>
</ol>
<p>So that&#8217;s our filtering approach.</p>
<p>There is one thing to add here. If we have group #1 and #2 and group#2 is a child of #1. And user selected to filter users which are both in #1 and #2, then we should perform a little optimization and search only for #2 because that will be the correct answer to the query. This situation is stupid, but we should act smart even in a stupid queries <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Maybe there are better solutions. We&#8217;re open to them! Moreover, we realize that there are more experienced developers that already solved such problem. Help us <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Tomorrow we have a meeting where we&#8217;ll be discussing the architecture, classes etc. I&#8217;ll upload our results on the weekends or early next week. This depends on the amount of work done during the meeting.<br />
Stay tuned! Subscribe to my blog&#8217;s RSS, share your opinions/suggestions in comments and don&#8217;t miss the next post in this series!</p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a title="Click me to see the sites." href="#" onclick="$$('div.d351').each( function(e) { e.visualEffect('slide_down',{duration:2.5}) }); return false;"><strong><em>Liked the post? Bookmark it</em></strong></a>
<br />
<div class="d351" style="overflow:hidden">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F19%2Fdatabase-sms-notification%2F&amp;title=Database+structure+and+filtering+approach.+SMS+Notification+system." rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F19%2Fdatabase-sms-notification%2F&amp;title=Database+structure+and+filtering+approach.+SMS+Notification+system." rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F19%2Fdatabase-sms-notification%2F" rel="nofollow" title="Add to&nbsp;Facebook"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/facebook.png" title="Add to&nbsp;Facebook" alt="Add to&nbsp;Facebook" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F19%2Fdatabase-sms-notification%2F&amp;title=Database+structure+and+filtering+approach.+SMS+Notification+system." rel="nofollow" title="Add to&nbsp;Google Bookmarks"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/google.png" title="Add to&nbsp;Google Bookmarks" alt="Add to&nbsp;Google Bookmarks" /></a>
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.netscape.com/submit/?U=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F19%2Fdatabase-sms-notification%2F&amp;T=Database+structure+and+filtering+approach.+SMS+Notification+system." rel="nofollow" title="Add to&nbsp;Netscape"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/netscape.png" title="Add to&nbsp;Netscape" alt="Add to&nbsp;Netscape" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F19%2Fdatabase-sms-notification%2F&amp;title=Database+structure+and+filtering+approach.+SMS+Notification+system." rel="nofollow" title="Add to&nbsp;Slashdot"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/slashdot.png" title="Add to&nbsp;Slashdot" alt="Add to&nbsp;Slashdot" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F19%2Fdatabase-sms-notification%2F&amp;title=Database+structure+and+filtering+approach.+SMS+Notification+system." rel="nofollow" title="Add to&nbsp;Stumble Upon"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/stumbleupon.png" title="Add to&nbsp;Stumble Upon" alt="Add to&nbsp;Stumble Upon" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F19%2Fdatabase-sms-notification%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home/?status=Check+out+Database+structure+and+filtering+approach.+SMS+Notification+system.+@+http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F19%2Fdatabase-sms-notification%2F" rel="nofollow" title="Add to&nbsp;Twitter"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/twitter.png" title="Add to&nbsp;Twitter" alt="Add to&nbsp;Twitter" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F19%2Fdatabase-sms-notification%2F&amp;t=Database+structure+and+filtering+approach.+SMS+Notification+system." rel="nofollow" title="Add to&nbsp;Yahoo My Web"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/yahoo.png" title="Add to&nbsp;Yahoo My Web" alt="Add to&nbsp;Yahoo My Web" /></a>
<br />
<a style="font-size:90%;text-align: right; " title="Click me to hide the sites." href="#" onclick="$$('div.d351').each( function(e) { e.visualEffect('slide_up',{duration:0.5}) }); return false;">Hide Sites</a>
</div>
</div>
<!-- Social Bookmarks END -->
<script type="text/javascript">$$('div.d351').each( function(e) { e.visualEffect('slide_up',{duration:0.5}) }); </script>

<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://programmersnotes.info/2010/03/19/database-sms-notification/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Requirements and Use Cases. SMS Notification System.</title>
		<link>http://programmersnotes.info/2010/03/18/requirements-use-cases-sms-notification/</link>
		<comments>http://programmersnotes.info/2010/03/18/requirements-use-cases-sms-notification/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 06:00:56 +0000</pubDate>
		<dc:creator>Konstantin Mirin</dc:creator>
				<category><![CDATA[OOP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[DB]]></category>
		<category><![CDATA[experiece]]></category>
		<category><![CDATA[modelling]]></category>
		<category><![CDATA[sms-notify]]></category>
		<category><![CDATA[UML]]></category>

		<guid isPermaLink="false">http://programmersnotes.info/?p=342</guid>
		<description><![CDATA[Background I&#8217;ve graduated in March 2010 and I don&#8217;t need to visit university any more. However, I enjoyed studying there and I know what challenges my fellow students-programmers have. That&#8217;s why I continue the job started this autumn – computer club, we call it “Geeks&#8217; Club”. Sure, we&#8217;re not true geeks there, but we tend [...]


No related posts.

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<h2><a name="background">Background</a></h2>
<p>I&#8217;ve graduated in March 2010 and I don&#8217;t need to visit university any more. However, I enjoyed studying there and I know what challenges my fellow students-programmers have. That&#8217;s why I continue the job started this autumn – computer club, we call it “Geeks&#8217; Club”. Sure, we&#8217;re not true geeks there, but we tend to be <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  So I&#8217;m helping students who&#8217;re interested in web-technologies and in object-oriented programming. I explain them things that are not covered in the standard university course. Things, that are more practical and they can be paid money for.</p>
<p><span id="more-342"></span></p>
<p>Here I&#8217;ll be covering both OOP and web-dev, but we&#8217;ll start from design hence OOP. The story began when some time passed after we started learning OOP at the club meetings and I decided that there is enough theory and separate examples, it&#8217;s time to build something practical that will be challenging for me too.<br />
I thought of different systems, but finally decided to pick up the SMS notification one. It requires both user interface, database, API (my friends want to communicate to it from standalone Java and C++ applications) and overall application design. In addition, I&#8217;d like such system to be deployed at our university and it is interesting for me to create one.</p>
<h2><a name="intro">Introduction</a></h2>
<p>This is going to be a series of articles, I&#8217;ll describe the progress and challenges we come across as we proceed with development. I think this kind of posts will be interesting for those who study OOP and want to apply what they&#8217;ve learned to some practical things. I&#8217;ll try to guide my students through the process using the iterative development methodology.</p>
<p>We have meetings once a week (on Saturdays), so I&#8217;ll post once or twice a week, depending on amount of work done on weekends and my free time during the week.</p>
<p>I think, this series will contain around 10 posts. We&#8217;re going to share the work done as an open-source project. There is nothing to share at the moment, so I&#8217;ll give the link when we code something <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2><a name="overview">System overview</a></h2>
<h3><a name="vision">Vision</a></h3>
<p>Obviously, the main purpose of the system is to send SMS notifications to students or tutors. These notifications may be quite different – from the timetable changes to some announcements or even warnings (e.g. “Due to the weather conditions, today is a day-off for all. Stay at home and have a good time”).</p>
<p>Actually the system isn&#8217;t that complex. Basically all it needs to do is to enable administrator pick a group of users, enter the message and send it through the SMS gateway. The tricky things start from “pick a group of users”. We want this to be as flexible as possible so we could use this system not only for university, but any other organization.</p>
<h3><a name="vision">University structure</a></h3>
<p>This is obvious to anyone who studied at the university in Ukraine, Russia and former USSR, but I&#8217;m not sure the structure is the same abroad. So we have the university. There are faculties (e.g. Computer Science, Philology etc). These faculties have specialties. For example, Computer Science faculty has 2 specialties – “Intellectual Systems of Decision-Making” (mine) and “Computer Engineering”. (For those interested about the difference, first one deals more with AI technologies while the latter – with system programming, networks etc).</p>
<p>Next level is “course”. We call it so, but actually that is the year of study. I know, there are special words for the 1st year students, for the 2nd etc. Here we just say “I&#8217;m on the first course”. That means “I&#8217;m studying the first year”.</p>
<p>All students that study the same specialty and are on the same course are called “Stream”. This is literal translation and I&#8217;m sure there is some more correct term. I&#8217;d be thankful if someone posts it in comments.</p>
<p>There are 2-4 groups in the “stream”. In our university they are names as follows: 101, 102, 103 etc. First number is course. In this case it is the first one. Second number is the faculty code. 0 is for computer science. And the third number is the group number. Thus 102 is the second group of first-year  students studying Computer Science. I realize that not all universities name groups like this, so we don&#8217;t want to stick to such naming in our product.</p>
<p>Now let&#8217;s go through the tutors and staff. There is a rector of a university. There are deans for every faculty. And all tutors are grouped by departments. Usually, departments relate to the faculty, but that&#8217;s not a rule. For example, on our faculty we have Department of Higher Mathematics, Department of Intellectual systems ans some others. One tutor usually belongs to one department.</p>
<p>In addition, there are different clubs for students like our “Geeks&#8217; Club”, translators&#8217; “Pickwick Club” etc. Some of these clubs (like ours) have departments (Web-development, OOP, Java, C++, Delphi, Administration etc). </p>
<p>We want to be able to filter users using all the above groups plus some more user-specific filters like age or gender.<br />
Let&#8217;s go through the planned features now.</p>
<h3><a name="userperspective">User perspective</a></h3>
<p>First of all, user can log in. User should enter his phone number and password. We&#8217;ll possibly add additional security for administrators. If administrator logs in, he enters his phone and password, but then a dynamic password is sent to his phone. And he completes login procedure only after he enters this dynamic password. We&#8217;re not sure if we&#8217;ll implement this. Your comments are welcome!</p>
<p>Next, user can edit his profile. He&#8217;ll have the following fields there:</p>
<ul>
<li>Phone</li>
<li>Email</li>
<li>Password (and confirmation)</li>
<li>Name, surname, patronymic</li>
<li>Gender</li>
<li>Birthday</li>
<li>ICQ</li>
<li>Faculty</li>
<li>Course (1st year, 2nd year etc)</li>
<li>Group</li>
<li>Clubs user is member of</li>
<li>Any tags user assigns to himself (e.g. “musician”)</li>
</ul>
<p>Plus user should check the option “receive SMS”.</p>
<p>However, user can&#8217;t edit phone directly because we&#8217;ll have to confirm it. So instead of giving him the field in the profile editing form, we&#8217;d rather give him a button or a link which will bring him a from where he puts new phone number and password. After that a dynamic password is sent to his phone via SMS and he enters this dynamic password and phone is updated.</p>
<p>Finally, user may register. When registering, he enters nearly the same data as when editing profile, but there is a dynamic password sent to him in order to confirm the phone number.<br />
All these screens are shown below.</p>
<div id="attachment_346" class="wp-caption aligncenter" style="width: 563px"><a href="http://programmersnotes.info/wp-content/uploads/2010/03/UserArea.png"><img src="http://programmersnotes.info/wp-content/uploads/2010/03/UserArea.png" alt="User area screens" title="UserArea" width="553" height="702" class="size-full wp-image-346" /></a><p class="wp-caption-text">User area screens</p></div>
<h3><a name="groupadmin">Group Administrator perspective</a></h3>
<p>Group administrator role may be assigned to the club&#8217;s leader, to the group monitor (or it&#8217;s better to say headman? What sound more “English”), to the tutor or headmaster. Basically everyone who needs to send notifications will have this role.</p>
<p>So, this type of users can do the same as the simple user plus searching users, sending email notifications and viewing statistics.<br />
Each group administrator will be limited to the groups he may view/notify. For example, headmaster can notify anyone. Tutor may notify all groups of students he tutors in. Group monitor may notify all students within his/her group.</p>
<p>Listing users and searching through them is done in the same screen. In the main part of the screen there is a list of users that are in the groups available to the group administrator. In the left side there is a “narrow search” panel which lists all filters that can be applied to the current set of users. Clicking the filter option (e.g. “Geeks&#8217; Club”) lists all users that fall into the current filter conditions. And it also refreshes the filtering options. For example, if there is no girls in the “Geeks&#8217; Club” then there is no point to show these option in the filter. This is harder to code, but it will bring excellent user experience.</p>
<p>In the right hand side there will be the “saved searches” panel. When you applied some searching criteria, you may save it with some label so you can quickly access this search in the future. Were going to create standard searches in addition to filtering to simplify the system&#8217;s usage.</p>
<p>This works as following. For example, you can view all Computer Faculty. But you need only girls from the Geeks&#8217; Club. So you filter by gender and then by club. And save this search as “Girls-geeks” <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  This immediately appears in the right “saved searches” panel.</p>
<p>These saved searched may be group-specific and user-specific. This basically means that when group admin saves search, he may select if he wants it to be private or he wants to share this search with other group administrators, who have access to the same groups as he does. We think, this will help users creating the searches that they really need. Sure, saved searched may be easily removed.</p>
<p>In the right side there will be also a “Send notification” panel. It will contain only textarea field and a “send” button. When you have your group ready, you type the message an click “send”. It asks for confirmation, displaying how much it would cost and sends it over.</p>
<p>Another page in the Group administrator&#8217;s  perspective is statistics. Here he&#8217;ll see how much messages he sent during the last day/week/month/overall and how much did it cost.</p>
<p>As we progress with development, we may add some settings, that will be the third page then. Here&#8217;s the filtering screen:</p>
<div id="attachment_344" class="wp-caption aligncenter" style="width: 568px"><a href="http://programmersnotes.info/wp-content/uploads/2010/03/FilterUsers.png"><img src="http://programmersnotes.info/wp-content/uploads/2010/03/FilterUsers.png" alt="Filter users screen" title="FilterUsers" width="558" height="370" class="size-full wp-image-344" /></a><p class="wp-caption-text">Filter users screen</p></div>
<p>Statistics screen is pretty straightforward, so we&#8217;ll omit it here.</p>
<h3><a name="administrator">Administrator&#8217;s perspective</a></h3>
<p>Administrator is almost god here <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  He can manage users, assign rights to the group administrators, set limits of SMS count, view logs and overall statistics.<br />
Users management screen will be nearly the same as filtering, with the only difference that when clicking the row with user&#8217;s you&#8217;ll see the profile screen with additional options:</p>
<ul>
<li>ban/unban</li>
<li>delete</li>
<li>phone editing does not require confirmation</li>
<li>administrator of (group selection)</li>
<li>notifications limit</li>
</ul>
<p>Logs and statistics screens are quite simple too.</p>
<h2><a name="usecase">Use cases</a></h2>
<p>After analyzing the above overview, we come up with the following use case diagram. It is pretty self-explanatory and written after the description above, so it is useful only as a summary.</p>
<div id="attachment_345" class="wp-caption aligncenter" style="width: 451px"><a href="http://programmersnotes.info/wp-content/uploads/2010/03/UseCaseModel.png"><img src="http://programmersnotes.info/wp-content/uploads/2010/03/UseCaseModel.png" alt="SMS Notification Use Cases" title="UseCaseModel" width="441" height="697" class="size-full wp-image-345" /></a><p class="wp-caption-text">SMS Notification Use Cases</p></div>
<p>Following the iterative development methodology, we should describe all usecases now, but I find this quite useless. After describing all usecases briefly, we should select 10% critical usecases and describe them in full. Full description includes the sequence of actions taken in the main success scenario and all alternative scenarios that may happen (e.g. DB error, connection failure, no users found etc). This is useful sometimes, but I think that for such simple application as this one, we ma skip this step either.</p>
<p>What is really useful about the iterative development at this stage is that it recommends picking 10% of the most critical usecases and start implementing them in full. By “critical” I usually mean those which may result in essential DB structure or application design changes. In our case there are 14 usecases.10% is 1.4 usecase. Let&#8217;s pick only one. The most critical usecase, that affects all the application design and DB structure is the user filtering. The success of an application depend on the stability and usability of this feature. So we should code it efficiently and then move to the other usecases.</p>
<p>I like this approach cause it is much more practical than designing the system from the interface. Changing interfaces and adopting them to core is much more simple and has less risk than doing vice versa.</p>
<p>So we decided to start with user filtering. The first thing we should create is the database structure. This will be covered in the tomorrow&#8217;s post.</p>
<p>I&#8217;d like to learn your opinion on all that. Maybe you can propose some better interface, or some nice filtering approach or just some idea for this. We&#8217;re open to all suggestions and comments! Thank you for reading my blog and following this project <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Subscribe to RSS and stay tuned!</p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a title="Click me to see the sites." href="#" onclick="$$('div.d342').each( function(e) { e.visualEffect('slide_down',{duration:2.5}) }); return false;"><strong><em>Liked the post? Bookmark it</em></strong></a>
<br />
<div class="d342" style="overflow:hidden">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F18%2Frequirements-use-cases-sms-notification%2F&amp;title=Requirements+and+Use+Cases.+SMS+Notification+System." rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F18%2Frequirements-use-cases-sms-notification%2F&amp;title=Requirements+and+Use+Cases.+SMS+Notification+System." rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F18%2Frequirements-use-cases-sms-notification%2F" rel="nofollow" title="Add to&nbsp;Facebook"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/facebook.png" title="Add to&nbsp;Facebook" alt="Add to&nbsp;Facebook" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F18%2Frequirements-use-cases-sms-notification%2F&amp;title=Requirements+and+Use+Cases.+SMS+Notification+System." rel="nofollow" title="Add to&nbsp;Google Bookmarks"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/google.png" title="Add to&nbsp;Google Bookmarks" alt="Add to&nbsp;Google Bookmarks" /></a>
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.netscape.com/submit/?U=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F18%2Frequirements-use-cases-sms-notification%2F&amp;T=Requirements+and+Use+Cases.+SMS+Notification+System." rel="nofollow" title="Add to&nbsp;Netscape"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/netscape.png" title="Add to&nbsp;Netscape" alt="Add to&nbsp;Netscape" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F18%2Frequirements-use-cases-sms-notification%2F&amp;title=Requirements+and+Use+Cases.+SMS+Notification+System." rel="nofollow" title="Add to&nbsp;Slashdot"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/slashdot.png" title="Add to&nbsp;Slashdot" alt="Add to&nbsp;Slashdot" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F18%2Frequirements-use-cases-sms-notification%2F&amp;title=Requirements+and+Use+Cases.+SMS+Notification+System." rel="nofollow" title="Add to&nbsp;Stumble Upon"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/stumbleupon.png" title="Add to&nbsp;Stumble Upon" alt="Add to&nbsp;Stumble Upon" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F18%2Frequirements-use-cases-sms-notification%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home/?status=Check+out+Requirements+and+Use+Cases.+SMS+Notification+System.+@+http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F18%2Frequirements-use-cases-sms-notification%2F" rel="nofollow" title="Add to&nbsp;Twitter"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/twitter.png" title="Add to&nbsp;Twitter" alt="Add to&nbsp;Twitter" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F18%2Frequirements-use-cases-sms-notification%2F&amp;t=Requirements+and+Use+Cases.+SMS+Notification+System." rel="nofollow" title="Add to&nbsp;Yahoo My Web"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/yahoo.png" title="Add to&nbsp;Yahoo My Web" alt="Add to&nbsp;Yahoo My Web" /></a>
<br />
<a style="font-size:90%;text-align: right; " title="Click me to hide the sites." href="#" onclick="$$('div.d342').each( function(e) { e.visualEffect('slide_up',{duration:0.5}) }); return false;">Hide Sites</a>
</div>
</div>
<!-- Social Bookmarks END -->
<script type="text/javascript">$$('div.d342').each( function(e) { e.visualEffect('slide_up',{duration:0.5}) }); </script>

<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://programmersnotes.info/2010/03/18/requirements-use-cases-sms-notification/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MySQL Workbench &#8211; The Database Modeling Tool for MySQL</title>
		<link>http://programmersnotes.info/2009/03/01/mysql-workbench-the-database-modeling-tool-for-mysql/</link>
		<comments>http://programmersnotes.info/2009/03/01/mysql-workbench-the-database-modeling-tool-for-mysql/#comments</comments>
		<pubDate>Sun, 01 Mar 2009 05:42:13 +0000</pubDate>
		<dc:creator>Konstantin Mirin</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Yii]]></category>
		<category><![CDATA[database design]]></category>
		<category><![CDATA[DB]]></category>
		<category><![CDATA[modelling]]></category>

		<guid isPermaLink="false">http://programmersnotes.info/?p=80</guid>
		<description><![CDATA[MySQL Workbench review based on my own usage experience. Pros and cons of the tool.


No related posts.

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<h2>The history</h2>
<p>In December I&#8217;ve got a project, that required sophisticated and quite complex DB and that DB was subject to change greatly during first development phase. Before that project I was using <a target="_blank" href="http://www.sparxsystems.com.au/">Sparx Enterprise Architect</a> both for application design and DB design. But, frankly speaking, it&#8217;s not good at databases, especially MySQL. So I decided to pick up a new DB modelling tool.<br />
<span id="more-80"></span></p>
<h2>Requirements</h2>
<p>My requirements to it were:</p>
<ul>
<li><strong>Convenient entering</strong> of the attributes and their types. When I have an idea, I want it to be recorded fast, I don&#8217;t want to spend time clicking different &#8220;add&#8221; and &#8220;save&#8221; buttons in order to enter table attributes</li>
<li><strong>Full MySQL features</strong> (including all types of indexes) and main storage engines support (MyISAM, InnoDB, MEMORY)</li>
<li><strong>Visual tables layout</strong> like in MS Access</li>
<li><strong>Maintaining table joins</strong> and involved indexes, visual creation of table connections</li>
<li><strong>SQL export</strong></li>
<li><strong>Free!</strong></li>
</ul>
<h2>On the way to perfection&#8230;</h2>
<p>I went through <a target="_blank" href="http://www.databaseanswers.org/modelling_tools.htm">this list</a> and installed and tried around 10 different tools and I didn&#8217;t like any of them. One has no visual modelling, other has inconvenient input, third has both, but doesn&#8217;t support a number of MySQL features. So finally I ended up with <a target="_blank" href="http://dev.mysql.com/workbench/">MySQL Workbench</a>. It gives me all I need and even more.</p>
<h2>Yes! It&#8217;s really perfect <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </h2>
<p><a target="_blank" href="http://dev.mysql.com/workbench/?page_id=11">Here</a> you may find a list of features together with versions comparison. You can read it yourself and I want to describe why I liked it:</p>
<h3>Nice design</h3>
<p>Yes, it matters. When you use Windows95-like program, you can&#8217;t feel as good as if you&#8217;re using excellent-designed one. Here is a screen:<br />
<div id="attachment_82" class="wp-caption aligncenter" style="width: 310px"><a href="http://programmersnotes.info/wp-content/uploads/2009/02/wb_model_table_editor11.png"><img src="http://programmersnotes.info/wp-content/uploads/2009/02/wb_model_table_editor1-300x238.png" alt="Model Overview" title="Model Overview" width="300" height="238" class="size-medium wp-image-82" /></a><p class="wp-caption-text">Model Overview</p></div></p>
<h3>Creating DB</h3>
<p>I liked their &#8220;schema approach&#8221;. When you create DB, you set the schema default encoding and all the tables in DB are automatically created in this encoding. Sure, you can change it for each table, but this is very helpful. I&#8217;ve also set up mydefault storage engine &#8211; InnoDB (MyISAM is default). This setting can be found in a seconds; everything is in it&#8217;s place (Tools -> Options -> MySQL).<br />
So now I can create my table without remembering that I should change some settings each time I create new table. That&#8217;s my first requirement.</p>
<h3>Creating tables</h3>
<p>I liked their template approach to the generic field names. Near every table has ID field. In my name conventions (since I&#8217;m using Yii framework, I follow their), ID field name is [tableName]ID. So I go to the Tools -> Options -> Model and set there:</p>
<ul>
<li>Primary key pattern &#8211; %table%ID</li>
<li>Primary key default type &#8211; INT(11)</li>
<li>Foreign key defaults (since I&#8217;m using InnoDB, which takes care of data integrity, I set this. I&#8217;ll tell more about this in my future posts about MySQL&#038;InnoDB)</li>
</ul>
<p>Three little settings, but it makes my life much more simple! Actually, you can set up the naming of the auto-generated index fields, but I don&#8217;t use it, I create all tables I need myself. However, Workbench can create cross table for Many-to-Many relation for you.<br />
Now I create the table (collation and engine are set automatically), go to the &#8220;fields&#8221; tab (tabs are in the bottom &#8211; I had problems finding them first time) and have my ID field created. Unfortunately, I can&#8217;t say that I want first letter in lower-case, so I correct it manually. Then start adding fields. It is very simple. First you double click on the empty row where should one name of the field, enter your name, press TAB, enter the field type (I usually enter 1-3 letters and press &#8220;Down&#8221; key, it selects correct type), press TAB again and you&#8217;re on the next field! So you just keep populating your attributes really fast! Then just tick NN (not null) and AI (auto increment) checkboxes and your table scheme is done. All indexes are set up on the next tab &#8211; Indexes except PRIMARY KEY. ID field is PRIMARY KEY by default. To add more fields there, select field and tick PRIMARY KEY checkbox in the right part of the tab.</p>
<h3>Visual layout</h3>
<p>Consider we created tables we need, now we advance to the scheme and connections. Double click &#8220;Add Diagram&#8221; in the top of the screen and you&#8217;re there. In the centre of the right pane you have tables you created. If you drag table from that list to your diagram, you&#8217;ll see big dot near it&#8217;s name. That&#8217;s also very convenient when you have a number of tables. Sure, here you can snap to grid, show/hide it, but that&#8217;s not so impressive.</p>
<h3>Visual grouping</h3>
<p>And this feature is mega-great! When you have huge DB, you can group tables using coloured layers:<br />
<div id="attachment_85" class="wp-caption aligncenter" style="width: 310px"><a href="http://programmersnotes.info/wp-content/uploads/2009/02/wb_diagam_zoomed_out11.png"><img src="http://programmersnotes.info/wp-content/uploads/2009/02/wb_diagam_zoomed_out1-300x239.png" alt="ER Diagram with coloured layers for grouping" title="ER diagram with layers" width="300" height="239" class="size-medium wp-image-85" /></a><p class="wp-caption-text">ER Diagram with coloured layers for grouping</p></div></p>
<h3>Visual connections</h3>
<p>Yes, it allows you to connect tables like you want. 1-1,1-N and N-M relations. If you prefer to create foreign keys automatically, yo can use these types of joins. I prefer to create all tables and fields and then connect it. So I click on the last icon in the left toolbar, select foreign key, then click &#8220;Pick referenced columns&#8221; and finally select the primary key I link to. I&#8217;m done. All InnoDB connections are automatically created.<br />
<div id="attachment_86" class="wp-caption aligncenter" style="width: 310px"><a href="http://programmersnotes.info/wp-content/uploads/2009/02/wb_diagam_fk_pick_columns11.png"><img src="http://programmersnotes.info/wp-content/uploads/2009/02/wb_diagam_fk_pick_columns1-300x239.png" alt="Creating relationship using existing columns" title="Creating relatinship" width="300" height="239" class="size-medium wp-image-86" /></a><p class="wp-caption-text">Creating relationship using existing columns</p></div></p>
<h3>SQL export</h3>
<p>Sure, SQL export is not new or impressive feature, but MySQL Workbench allows you not only to create SQL for the scheme, but also to create ALTER DB script for the CREATE DB script already created. For example, you designed a great DB, exported to SQL query, installed on server and then your client wants changes. You open MySQL Workbench project, make necessary changes and then create ALTER script. Very convenient thing <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Integration with Yii</h2>
<p>One clever guy (<a target="_blank" href="http://blog.orite.com.au/web_development/2009-02-06/mwbmodelcommand-yii-framework-and-mysql-workbench/">unikly</a>) created the Yii shell command, that allows to use mwb file instead of DB connection when creating Yii DB models. This command is available on the Yii <a target="_blank" href="http://www.yiiframework.com/extension/mwbmodelcommand/">extensions page</a>. As for me, it&#8217;s a very big plus.</p>
<h2>A fly in the ointment</h2>
<p>I&#8217;ve noticed several bad things in this software:</p>
<ul>
<li>When DB becomes huge, you need a good machine to work with it comfortably. It takes too much resources</li>
<li>Some interface elements are not evident (In the DB overview screen lowest part has tabs both on the top and on the bottom. Top tabs &#8211; switch between tables, bottom tabs &#8211; switch between table&#8217;s sections (properties, fields, indexes)</li>
<li>When creating joins, it doesn&#8217;t maintain the uniqueness of foreign indexes names. Take a close look at the export script (and watch for constraints and auto-created foreign keys) when it fails in phpMyAdmin (or other tool)</li>
</ul>
<p>
<strong>Disclaimer:</strong> Screenshots are taken from <a target="_blank" href="http://dev.mysql.com/workbench/?page_id=35">MySQL Workbench</a> site, I was lazy to take my own ones.</p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a title="Click me to see the sites." href="#" onclick="$$('div.d80').each( function(e) { e.visualEffect('slide_down',{duration:2.5}) }); return false;"><strong><em>Liked the post? Bookmark it</em></strong></a>
<br />
<div class="d80" style="overflow:hidden">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F01%2Fmysql-workbench-the-database-modeling-tool-for-mysql%2F&amp;title=MySQL+Workbench+%26%238211%3B+The+Database+Modeling+Tool+for+MySQL" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F01%2Fmysql-workbench-the-database-modeling-tool-for-mysql%2F&amp;title=MySQL+Workbench+%26%238211%3B+The+Database+Modeling+Tool+for+MySQL" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F01%2Fmysql-workbench-the-database-modeling-tool-for-mysql%2F" rel="nofollow" title="Add to&nbsp;Facebook"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/facebook.png" title="Add to&nbsp;Facebook" alt="Add to&nbsp;Facebook" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F01%2Fmysql-workbench-the-database-modeling-tool-for-mysql%2F&amp;title=MySQL+Workbench+%26%238211%3B+The+Database+Modeling+Tool+for+MySQL" rel="nofollow" title="Add to&nbsp;Google Bookmarks"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/google.png" title="Add to&nbsp;Google Bookmarks" alt="Add to&nbsp;Google Bookmarks" /></a>
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.netscape.com/submit/?U=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F01%2Fmysql-workbench-the-database-modeling-tool-for-mysql%2F&amp;T=MySQL+Workbench+%26%238211%3B+The+Database+Modeling+Tool+for+MySQL" rel="nofollow" title="Add to&nbsp;Netscape"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/netscape.png" title="Add to&nbsp;Netscape" alt="Add to&nbsp;Netscape" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F01%2Fmysql-workbench-the-database-modeling-tool-for-mysql%2F&amp;title=MySQL+Workbench+%26%238211%3B+The+Database+Modeling+Tool+for+MySQL" rel="nofollow" title="Add to&nbsp;Slashdot"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/slashdot.png" title="Add to&nbsp;Slashdot" alt="Add to&nbsp;Slashdot" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F01%2Fmysql-workbench-the-database-modeling-tool-for-mysql%2F&amp;title=MySQL+Workbench+%26%238211%3B+The+Database+Modeling+Tool+for+MySQL" rel="nofollow" title="Add to&nbsp;Stumble Upon"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/stumbleupon.png" title="Add to&nbsp;Stumble Upon" alt="Add to&nbsp;Stumble Upon" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F01%2Fmysql-workbench-the-database-modeling-tool-for-mysql%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home/?status=Check+out+MySQL+Workbench+%26%238211%3B+The+Database+Modeling+Tool+for+MySQL+@+http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F01%2Fmysql-workbench-the-database-modeling-tool-for-mysql%2F" rel="nofollow" title="Add to&nbsp;Twitter"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/twitter.png" title="Add to&nbsp;Twitter" alt="Add to&nbsp;Twitter" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F01%2Fmysql-workbench-the-database-modeling-tool-for-mysql%2F&amp;t=MySQL+Workbench+%26%238211%3B+The+Database+Modeling+Tool+for+MySQL" rel="nofollow" title="Add to&nbsp;Yahoo My Web"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/yahoo.png" title="Add to&nbsp;Yahoo My Web" alt="Add to&nbsp;Yahoo My Web" /></a>
<br />
<a style="font-size:90%;text-align: right; " title="Click me to hide the sites." href="#" onclick="$$('div.d80').each( function(e) { e.visualEffect('slide_up',{duration:0.5}) }); return false;">Hide Sites</a>
</div>
</div>
<!-- Social Bookmarks END -->
<script type="text/javascript">$$('div.d80').each( function(e) { e.visualEffect('slide_up',{duration:0.5}) }); </script>

<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://programmersnotes.info/2009/03/01/mysql-workbench-the-database-modeling-tool-for-mysql/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss>

