<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'><id>tag:blogger.com,1999:blog-375697951860081841.post3033087006686683007..comments</id><updated>2008-07-15T16:32:11.098+01:00</updated><category term='linux'/><category term='idea'/><category term='business'/><category term='Microsoft'/><category term='MySQL'/><category term='Programming Lanugage'/><category term='SQL'/><category term='ETL'/><category term='Email'/><category term='China'/><category term='pentaho'/><category term='informatica'/><category term='Jobs'/><category term='MS SQL'/><category term='open source'/><category term='federated tables'/><category term='Oracle'/><category term='data warehousing'/><category term='Google'/><category term='triggers'/><category term='decision tables'/><category term='PHP'/><category term='Views'/><category term='configuration-management'/><category term='event-driven publishing'/><category term='Data'/><category term='talend'/><category term='Agile'/><category term='business rules'/><category term='Decision tree'/><category term='ubuntu'/><category term='caching'/><category term='Data mining'/><category term='expert system'/><category term='database'/><category term='Excel'/><title type='text'>Comments on Jonathan Levin's Axioms: SQL is in Fact a Programming Language</title><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.jonathanlevin.co.uk/feeds/3033087006686683007/comments/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/375697951860081841/3033087006686683007/comments/default'/><link rel='alternate' type='text/html' href='http://www.jonathanlevin.co.uk/2008/04/sql-is-in-fact-programming-language.html'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/__8lgzcJRF8U/SOAxOE9FX9I/AAAAAAAAIf0/gzlxBGxU_gU/S220/mesmiling_cv.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>7</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-4171394971521032089</id><published>2008-07-15T16:32:00.000+01:00</published><updated>2008-07-15T16:32:00.000+01:00</updated><title type='text'>i come from a sybase/db2 programming background. w...</title><content type='html'>i come from a sybase/db2 programming background. we use the entity attribute value pattern very very extensively. there is a very simple way to get around complex queries. use the pattern&lt;BR/&gt;&lt;BR/&gt;select entity.id,&lt;BR/&gt;case when attribute.attrib_id = 1 then attribute.attrib_value end as attrib1,&lt;BR/&gt;case when attribute.attrib_id = 2 then attribute.attrib_value end as attrib2&lt;BR/&gt;from entity e, attribute a&lt;BR/&gt;where e.entity_id = a.entity_id&lt;BR/&gt;and (your conditions here)&lt;BR/&gt;&lt;BR/&gt;im not sure if the above is possible in mysql.&lt;BR/&gt;&lt;BR/&gt;btw we use the above in entities and attributes having upwards of 50 million rows (and more than 20gb each) without any problems. if you have proper indexes queries are fairly fast.&lt;BR/&gt;&lt;BR/&gt;we have very fast apps running on top of the above tables.&lt;BR/&gt;&lt;BR/&gt;i wouldn;t say the above is an antipattern. i think the problem here is ignorance of techniques in sql.&lt;BR/&gt;&lt;BR/&gt;thx,&lt;BR/&gt;ks</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/375697951860081841/3033087006686683007/comments/default/4171394971521032089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/375697951860081841/3033087006686683007/comments/default/4171394971521032089'/><link rel='alternate' type='text/html' href='http://www.jonathanlevin.co.uk/2008/04/sql-is-in-fact-programming-language.html?showComment=1216135920000#c4171394971521032089' title=''/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/blank.gif'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.jonathanlevin.co.uk/2008/04/sql-is-in-fact-programming-language.html' ref='tag:blogger.com,1999:blog-375697951860081841.post-3033087006686683007' source='http://www.blogger.com/feeds/375697951860081841/posts/default/3033087006686683007' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-595233186'/></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-4934886674512356880</id><published>2008-04-04T13:04:00.000+01:00</published><updated>2008-04-04T13:04:00.000+01:00</updated><title type='text'>"My short answer is: if you can't describe your da...</title><content type='html'>"My short answer is: if you can't describe your data, then SQL isn't the right tool to query it."&lt;BR/&gt;&lt;BR/&gt;Well, in this case, the data can be perfectly described, just not at the same time as the database schema was designed.&lt;BR/&gt;&lt;BR/&gt;Whether it is "highly normalized" or "not normalized at all" is a matter of perspective. &lt;BR/&gt;&lt;BR/&gt;From the point of view of the developers of the original application, that could not see whatever custom attributes the users would be adding, this EAV pattern is a normalized design to solve the problem of custom attributes. The could also have created a bunch of "spare" or "extra" columns in the existing tables which would depending on what they would be used for hardly be better normalized.&lt;BR/&gt;&lt;BR/&gt;On another level, it is more arbitrary than it may seem whether something should be considered to be unnormalized or 1st normal form. &lt;BR/&gt;&lt;BR/&gt;For example, take phone numbers. In some cases, we don't mind the phone number having a structure of it's own and we choose to regard it as an atomic value. In other cases, we want to separately store and search parts like country and area codes. Similar cases are URLs and email addresses.&lt;BR/&gt;&lt;BR/&gt;For multivalued attributes, we can witness the same. Sometimes it might be necessary to store someones initials. Although we know that each letter stands for a proper name, we will usually choose to treat it as an atomic value.&lt;BR/&gt;&lt;BR/&gt;In the end, the requirements of the application will govern what will be considered an atomic value. There is no objective generic criterion that can tell us that.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/375697951860081841/3033087006686683007/comments/default/4934886674512356880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/375697951860081841/3033087006686683007/comments/default/4934886674512356880'/><link rel='alternate' type='text/html' href='http://www.jonathanlevin.co.uk/2008/04/sql-is-in-fact-programming-language.html?showComment=1207310640000#c4934886674512356880' title=''/><author><name>Roland Bouman</name><uri>http://www.blogger.com/profile/13365137747952711328</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://www.xcdsql.org/people/rbouman/roland.jpg'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.jonathanlevin.co.uk/2008/04/sql-is-in-fact-programming-language.html' ref='tag:blogger.com,1999:blog-375697951860081841.post-3033087006686683007' source='http://www.blogger.com/feeds/375697951860081841/posts/default/3033087006686683007' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-1400074851'/></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-2732684820036489500</id><published>2008-04-04T04:29:00.000+01:00</published><updated>2008-04-04T04:29:00.000+01:00</updated><title type='text'>Yes, adding an extra table (or tables) to duplicat...</title><content type='html'>Yes, adding an extra table (or tables) to duplicate the data is an important first step.&lt;BR/&gt;&lt;BR/&gt;The next step is to DROP the EAV table!  :-)&lt;BR/&gt;&lt;BR/&gt;You shouldn't describe EAV as "highly normalized."  In fact, the opposite is true - EAV is not a normalized design at all.  &lt;BR/&gt;&lt;BR/&gt;It's not even in 1st normal form, because it uses the attr_value column for all attributes in the relation.  In a normalized design, each logical attribute should be stored in a distinct column.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/375697951860081841/3033087006686683007/comments/default/2732684820036489500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/375697951860081841/3033087006686683007/comments/default/2732684820036489500'/><link rel='alternate' type='text/html' href='http://www.jonathanlevin.co.uk/2008/04/sql-is-in-fact-programming-language.html?showComment=1207279740000#c2732684820036489500' title=''/><author><name>Bill Karwin</name><uri>http://www.blogger.com/profile/13004667086865377598</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://www.karwin.com/images/BK-portrait-260x360.png'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.jonathanlevin.co.uk/2008/04/sql-is-in-fact-programming-language.html' ref='tag:blogger.com,1999:blog-375697951860081841.post-3033087006686683007' source='http://www.blogger.com/feeds/375697951860081841/posts/default/3033087006686683007' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-1913967369'/></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-2766220017898155668</id><published>2008-04-04T02:22:00.000+01:00</published><updated>2008-04-04T02:22:00.000+01:00</updated><title type='text'>@bill karwin&lt;br&gt;I saw that you will be speaking in...</title><content type='html'>@bill karwin&lt;BR/&gt;I saw that you will be speaking in MySQL conference and I have to say that your topic seemed the most interesting to me :)&lt;BR/&gt;So please link the audio/video/slide files somewhere so I can see afterwards.&lt;BR/&gt;&lt;BR/&gt;Regarding the design of this database, I just call it "highly normalized". The people who made the database had to factor in many different circumstances, locations in which it could be deployed and languages that it could be used with. So they opted to do it this way.&lt;BR/&gt;&lt;BR/&gt;My main problem is that if you want to produce reports of some kind, its very very slow. &lt;BR/&gt;&lt;BR/&gt;I worked somwhere else where they had very much the same problem and it was my task to make it go faster.&lt;BR/&gt;&lt;BR/&gt;So I suggest just having an extra table (or atleast view) that duplicates the data from many smaller tables and integrates them.&lt;BR/&gt;&lt;BR/&gt;&lt;BR/&gt;On topic, to do this in java would probably taken 10x more lines to develop.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/375697951860081841/3033087006686683007/comments/default/2766220017898155668'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/375697951860081841/3033087006686683007/comments/default/2766220017898155668'/><link rel='alternate' type='text/html' href='http://www.jonathanlevin.co.uk/2008/04/sql-is-in-fact-programming-language.html?showComment=1207272120000#c2766220017898155668' title=''/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.jonathanlevin.co.uk/2008/04/sql-is-in-fact-programming-language.html' ref='tag:blogger.com,1999:blog-375697951860081841.post-3033087006686683007' source='http://www.blogger.com/feeds/375697951860081841/posts/default/3033087006686683007' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-878583402'/></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-7742158104647910266</id><published>2008-04-04T02:18:00.000+01:00</published><updated>2008-04-04T02:18:00.000+01:00</updated><title type='text'>My short answer is:  if you can't describe your da...</title><content type='html'>My short answer is:  if you can't describe your data, then SQL isn't the right tool to query it.&lt;BR/&gt;&lt;BR/&gt;Sometimes you need semi-structured data, or you need the capability of adding attributes without changing the application code or the database metadata.  &lt;BR/&gt;&lt;BR/&gt;In those cases, you are asking for a greater amount of flexibility than SQL was designed to provide.  Every programming task makes certain assumptions to achieve simplicity, and SQL makes the assumption that a given entity has a stable set of attributes.  &lt;BR/&gt;&lt;BR/&gt;EAV breaks this assumption -- it's designed to accommodate dynamic attributes.  But it should be no surprise that the resulting SQL isn't very graceful.&lt;BR/&gt;&lt;BR/&gt;There are emerging standards that treat data and metadata as virtually the same thing, and allow both to be dynamic and queriable.  RDF/XML is one example, and there's even a standard query language for it -- SPARQL.&lt;BR/&gt;&lt;BR/&gt;I'd say we're 10+ years years away from having de facto SPARQL interfaces as common as SQL interfaces, and RDF data stores that are as efficient as RDBMS products are today.&lt;BR/&gt;&lt;BR/&gt;In the meantime, EAV can be used for semi-structured data.  Though we must recognize it comes at a high cost, and perhaps in the majority of cases where it is used, it'd be simpler to add attributes with ALTER TABLE ADD COLUMN.&lt;BR/&gt;&lt;BR/&gt;Other options include a hybrid between conventional and EAV tables.  Store common attributes in the conventional way as columns, but allow extended attributes to be stored in an EAV table referencing the conventional table.  At least this allows some queries to avoid the EAV table, if the query only needs to reference the base set of attributes.&lt;BR/&gt;&lt;BR/&gt;Another option is to use "subtables" that extend a parent table, just like an object-oriented derived class adds properties and methods to those inherited from its parent class.  It takes a join to reconstitute the full row, but it's better than EAV which requires a join per attribute.&lt;BR/&gt;&lt;BR/&gt;All the solutions naturally add complexity, and therefore you should evaluate them on a case-by-case basis.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/375697951860081841/3033087006686683007/comments/default/7742158104647910266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/375697951860081841/3033087006686683007/comments/default/7742158104647910266'/><link rel='alternate' type='text/html' href='http://www.jonathanlevin.co.uk/2008/04/sql-is-in-fact-programming-language.html?showComment=1207271880000#c7742158104647910266' title=''/><author><name>Bill Karwin</name><uri>http://www.blogger.com/profile/13004667086865377598</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://www.karwin.com/images/BK-portrait-260x360.png'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.jonathanlevin.co.uk/2008/04/sql-is-in-fact-programming-language.html' ref='tag:blogger.com,1999:blog-375697951860081841.post-3033087006686683007' source='http://www.blogger.com/feeds/375697951860081841/posts/default/3033087006686683007' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-1913967369'/></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-4345329676918549824</id><published>2008-04-03T21:18:00.000+01:00</published><updated>2008-04-03T21:18:00.000+01:00</updated><title type='text'>Hi!&lt;br&gt;&lt;br&gt;yes - definitely an Enity Attribute (an...</title><content type='html'>Hi!&lt;BR/&gt;&lt;BR/&gt;yes - definitely an Enity Attribute (anti)pattern.&lt;BR/&gt;&lt;BR/&gt;This design should be shunned because of how cumbersome and opaque it is to code against it. All the ID's in the join clause to pick the right attributes are a tell-tale.&lt;BR/&gt;&lt;BR/&gt;But still...what if you have an application like MS Project: it lets you add custom properties to tasks, resources, etc. And, I've done a few projects where we really needed that to calculate custom performance indicators for project progress. Under the hood, MS Project has a entity value module in the database schema to implement this, and indeed - you get these typical queries, which sucks. &lt;BR/&gt;&lt;BR/&gt;But what about the alternatives? Surely, MS Project could just add a new column for a custom property, but the problem is that there are different types of projects and we'd end up with many columns that are basically useless to most types of projects. So that does not seem a good solution. Alternatively, a separate table could be created to hold the custom properties for a single project or group of projects of a certain type.&lt;BR/&gt;&lt;BR/&gt;The disadvantage of modifying the schema to accomodate custom properties would mean that all users that save the project in the db would need to have the privileges to ALTER or CREATE tables. After that, access to those new objects must also be granted to all other users that might need to read those projects.&lt;BR/&gt;&lt;BR/&gt;Not at all impossible, but still, application users with the rights to create database objects....&lt;BR/&gt;&lt;BR/&gt;Another option would be to indeed store all those custom things in some kind of semi-structured format such as XML. But would that really make it better? I seriously doubt it - esp. once we need to combine date stored in custom properties with other data in the db, I think I'd stil rather settle for an entity-attribute approach - rather that than springling XQuery / XPath constructs in my queries to get it done - I mean, it seems a cure that's worse than the disease.&lt;BR/&gt;&lt;BR/&gt;So - what are your thoughts? How to deal with partially extensible datamodels/ structures in relational databases? Should we just give up, or put up with a number of these annoying edges? I really don't know...</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/375697951860081841/3033087006686683007/comments/default/4345329676918549824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/375697951860081841/3033087006686683007/comments/default/4345329676918549824'/><link rel='alternate' type='text/html' href='http://www.jonathanlevin.co.uk/2008/04/sql-is-in-fact-programming-language.html?showComment=1207253880000#c4345329676918549824' title=''/><author><name>Roland Bouman</name><uri>http://www.blogger.com/profile/13365137747952711328</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://www.xcdsql.org/people/rbouman/roland.jpg'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.jonathanlevin.co.uk/2008/04/sql-is-in-fact-programming-language.html' ref='tag:blogger.com,1999:blog-375697951860081841.post-3033087006686683007' source='http://www.blogger.com/feeds/375697951860081841/posts/default/3033087006686683007' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-1400074851'/></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-3221405927566778325</id><published>2008-04-03T19:22:00.000+01:00</published><updated>2008-04-03T19:22:00.000+01:00</updated><title type='text'>LOL!  Yes, SQL is a programming language.  And lik...</title><content type='html'>LOL!  Yes, SQL is a programming language.  And like most programming languages, there is a graceful way to do design and architecture and then there is the way that I call "blecherous" (it makes you say "blechh!").&lt;BR/&gt;&lt;BR/&gt;As soon as I saw the fourth field in your select-list I knew what was up:&lt;BR/&gt;&lt;BR/&gt;    lastname.CONATTR_VALUE&lt;BR/&gt;&lt;BR/&gt;I feel sure this is an instance of a common SQL design blunder called Entity-Attribute-Value.  It's not your fault they designed the database this way, but now you can see how difficult it makes your job using that design.&lt;BR/&gt;&lt;BR/&gt;People who design their database with Entity-Attribute-Value practically don't need a SQL database at all -- they need an XML file.&lt;BR/&gt;&lt;BR/&gt;I'm currently writing a book called "SQL Antipatterns" and EAV is high on the list.&lt;BR/&gt;&lt;BR/&gt;I'm also presenting "SQL Antipatterns" as a tutorial at the MySQL Conference on April 14.&lt;BR/&gt;http://en.oreilly.com/mysql2008/public/schedule/detail/1639&lt;BR/&gt;&lt;BR/&gt;More details here:&lt;BR/&gt;http://karwin.blogspot.com/2008/03/speaking-at-mysql-conference.html</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/375697951860081841/3033087006686683007/comments/default/3221405927566778325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/375697951860081841/3033087006686683007/comments/default/3221405927566778325'/><link rel='alternate' type='text/html' href='http://www.jonathanlevin.co.uk/2008/04/sql-is-in-fact-programming-language.html?showComment=1207246920000#c3221405927566778325' title=''/><author><name>Bill Karwin</name><uri>http://www.blogger.com/profile/13004667086865377598</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://www.karwin.com/images/BK-portrait-260x360.png'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.jonathanlevin.co.uk/2008/04/sql-is-in-fact-programming-language.html' ref='tag:blogger.com,1999:blog-375697951860081841.post-3033087006686683007' source='http://www.blogger.com/feeds/375697951860081841/posts/default/3033087006686683007' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-1913967369'/></entry></feed>
