<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Watt&#39;s What</title>
    <link>https://wattswhat.org/</link>
    <description>Recent content on Watt&#39;s What</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Sat, 20 Aug 2016 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://wattswhat.org/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>About</title>
      <link>https://wattswhat.org/about/</link>
      <pubDate>Sat, 20 Aug 2016 00:00:00 +0000</pubDate>
      
      <guid>https://wattswhat.org/about/</guid>
      <description>

&lt;blockquote&gt;
&lt;p&gt;Strive for simple when you can, be pragmatic when you can’t.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Welcome to my (Nicki Watt’s) personal blog and website where all views, thoughts and ideas expressed here are my own.&lt;/p&gt;

&lt;p&gt;I am a techie who enjoys problem solving, making stuff work, and exploring technologies and approaches which can enable this. I relish engaging in a good architectural design or challenge, and statements like &amp;ldquo;it can&amp;rsquo;t be done&amp;rdquo; simply spur me on rather than deter me! Less is often more, and am thus also partial to a good proverb- they tend to convey the essence of what you want to say in a language everyone can understand. My own proverbial motto is “Strive for simple when you can, be pragmatic when you can’t”&lt;/p&gt;

&lt;h2 id=&#34;professional-info&#34;&gt;Professional info&lt;/h2&gt;

&lt;p&gt;I currently work as a lead consultant at &lt;a href=&#34;http://www.opencredo.com/&#34;&gt;OpenCredo&lt;/a&gt; helping companies embrace, build and deliver their solutions, with a current focus on Cloud, infrastructure as code, continuous integration and delivery and various NoSQL technologies. Along with my colleagues at OpenCredo I have also authored the book &lt;a href=&#34;http://www.manning.com/partner&#34;&gt;Neo4j In Action&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Have questions or suggestions? Feel free to &lt;a href=&#34;https://twitter.com/techiewatt&#34;&gt;ask me on Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Kubernetes on Mesos on Google Cloud – Version Alignment</title>
      <link>https://wattswhat.org/2015/02/kubernetes-on-mesos-on-google-cloud-version-alignment/</link>
      <pubDate>Mon, 02 Feb 2015 00:00:00 +0000</pubDate>
      
      <guid>https://wattswhat.org/2015/02/kubernetes-on-mesos-on-google-cloud-version-alignment/</guid>
      <description>

&lt;p&gt;I was recently trying to follow the instructions in the &lt;a href=&#34;http://mesosphere.com/docs/tutorials/kubernetes-mesos-gcp/&#34;&gt;tutorial&lt;/a&gt; by &lt;a href=&#34;http://mesosphere.com/&#34;&gt;Mesosphere&lt;/a&gt; detailing how to run &lt;a href=&#34;http://mesosphere.com/docs/tutorials/kubernetes-mesos-gcp/&#34;&gt;Kubernetes on Mesos on the Google Cloud Platform&lt;/a&gt;. The tutorial (At time of writing) did not quite work for me out the box and I had to make a few adjustments to get it working. This simply details a few of the extra steps I needed to take to get this setup working for me. This should hopefully mean that those who find themselves in a similar situation, can avoid running into my same issue upfront, and thus get to a working version faster! The Mesosphere team do update the tutorials periodically, usually when new releases occur, so the official tutorial may well be updated in due course in which case this entry will probably be redundant. But until then, for those who want to try this out now, I hope this can help!&lt;/p&gt;

&lt;h2 id=&#34;underlying-issue&#34;&gt;Underlying issue&lt;/h2&gt;

&lt;p&gt;The underlying cause of all my problems was centred around the fact that I was mixing Mesos versions in various places. In the pre-requisite list in the tutorial, you need to have a Mesosphere cluster on Google Compute Engine. (BTW Google provides you with $300 worth of &lt;a href=&#34;https://cloud.google.com/free-trial/&#34;&gt;free trial Google compute resources&lt;/a&gt; to play with). You however, are not in control of what version of Mesos is deployed for you by Mesosphere, and this is where I came unstuck. I was blindly following the instructions (centred around 0.21.0 at the time of writing) whilst Mesosphere had provisioned me a 0.21.1 cluster. Apparently the kubernetes-mesos framework is currently using the native Mesos binding compiled against a specific version of Mesos. So if the versions are out of sync, as mine were then issues may arise. My main issue was that my pods were simply not able to run on my minions. They appeared to stay in the “Pending” state forever.&lt;/p&gt;

&lt;h2 id=&#34;steps-to-resolve&#34;&gt;Steps to resolve&lt;/h2&gt;

&lt;p&gt;The basic resolution strategy is to: &lt;em&gt;Adjust everything in the tutorial to align with whatever Mesos version Mesosphere ultimately provisions for you in the Google cloud&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Practically this is what you need to do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Follow the instructions for setting up your Mesosphere cluster on Google Compute Engine as per normal.&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Build the Kubernetes-Mesos executables-&lt;/strong&gt; When you reach this step then:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;After executing the first (dpkg) command, take note of the Mesos version which has been provisioned for you as you will use this in subsequent steps. For example running the step below I can see the main Mesos version is 0.21.1&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ dpkg -l | grep -e mesos
ii mesos 0.21.1-1.2.debian77 amd64 Cluster resource manager ...
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;In addition to simply cloning the git repo in the next command, you need to ensure you are using a version of the &lt;a href=&#34;https://github.com/mesosphere/kubernetes-mesos&#34;&gt;kubernetes-mesos&lt;/a&gt; code compatible with the Mesos version you are actually running against. There is actually &lt;a href=&#34;https://github.com/mesosphere/kubernetes-mesos/blob/master/README.md#tutorial&#34;&gt;a note about this tutorial in the readme&lt;/a&gt; in the kubernetes-mesos Github repo stating that this tutorial is not necessarily always kept in sync with the repo, and it is suggested that tutorial users stick with the 0.3.x releases to ensure everything still works. In my case &lt;a href=&#34;https://github.com/mesosphere/kubernetes-mesos/releases/tag/v0.3.2&#34;&gt;v0.3.2&lt;/a&gt; was the latest kubernetes-mesos release compatible with Mesos 0.21.1&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git clone https://github.com/mesosphere/kubernetes-mesos k8sm
cd k8sm
git checkout v0.3.2
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;The final step under this section is to run the kubernetes-mesos docker image. Once again, modify the image name to use a docker image compatible with the version of Mesos you are running. Note the use of build-mesos-0.21.1-compat docker image, instead of build-mesos-0.21.0-compat&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mkdir -p bin &amp;amp;&amp;amp; sudo docker run --rm \ 
-v $(pwd)/bin:/target -v $(pwd)/k8sm:/snapshot \ 
jdef/kubernetes-mesos:build-mesos-0.21.1-compat
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Run the Example Guestbook App-&lt;/strong&gt; When you get here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provided you have checked out the correct git tag in the previous step, the example code should be compatible with your Mesos version. Note however that on the tutorial itself, the link to the example instructions is to an older v0.2.2 version, so if you follow the link, you may be following incorrect instructions.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thats it! Everything else should work just fine!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The SQL of trust in a NoSQL world</title>
      <link>https://wattswhat.org/2015/01/sql-vs-nosql-and-the-sql-of-trust-in-a-nosql-world/</link>
      <pubDate>Tue, 20 Jan 2015 00:00:00 +0000</pubDate>
      
      <guid>https://wattswhat.org/2015/01/sql-vs-nosql-and-the-sql-of-trust-in-a-nosql-world/</guid>
      <description>




    
    
        
        
        
        
    

    
    
    

    
    




    
    
        
    


    

    
        &lt;span class=&#34;image left&#34;&gt;
            &lt;img src=&#34;https://wattswhat.org/img/2015/01/sql-of-trust-logo.jpg&#34; alt=&#34;feature&#34; /&gt;
        &lt;/span&gt;
    



&lt;p&gt;From the movie &lt;a href=&#34;http://www.moviequotedb.com/movies/meet-the-parents.html&#34;&gt;Meet the Parents&lt;/a&gt;, the “circle of trust” quote is amongst other things, used to infer that you can only really be part of the family once you are &lt;em&gt;inside&lt;/em&gt; “the circle of trust”. &lt;a href=&#34;http://en.wikipedia.org/wiki/NoSQL&#34;&gt;NoSQL&lt;/a&gt; vendors are desperate to attain a greater de facto acceptance as heavyweights and household names to be relied on in the broader software development community, and especially in the lucrative enterprise space. To this end, there appears to be a courting of a few of the battle hardened supporters from the &lt;a href=&#34;http://en.wikipedia.org/wiki/Relational_database_management_system&#34;&gt;RDBMS&lt;/a&gt; world with the lure of “some sort of familiarity” to their current known world in order to help try and break into this circle of trust. One such area of familiarity is &lt;a href=&#34;http://en.wikipedia.org/wiki/SQL&#34;&gt;SQL&lt;/a&gt;, and it is interesting to observe the different degrees to which some NoSQL vendors have gone in adapting their respective querying languages to cater for this fact. Now let me be clear that there is absolutely nothing wrong with this approach – provided of course it does not completely skew and dumb down the original benefits of the underlying datastore in question.&lt;/p&gt;

&lt;p&gt;It should come as no surprise that when it comes to data, the vast majority of developers today (yes even in 2015) still &lt;em&gt;think&lt;/em&gt; in structured RDBMS terms, and when it comes to querying data – SQL is probably the most prominent query language still out there. This simply stems from the fact that NoSQL databases are still relatively young compared to their RDBMS counterparts which have been around for a lot longer.&lt;/p&gt;

&lt;p&gt;N*SQL (No/NewSQL) databases are by definition, going to be very different to RDBMS and querying the data from them will more than likely be different as well. So is there any common ground here, specifically is it possible for a structured query language like SQL to easily translate or morph to being used in an unstructured context as well? Should we even trust this approach? SQL vs NoSQL? Time for some examples …&lt;/p&gt;

&lt;h2 id=&#34;setting-the-scene-an-rdbms-example&#34;&gt;Setting the scene – an RDBMS example&lt;/h2&gt;

&lt;p&gt;Suppose we are modelling an ordering system where we have &lt;code&gt;ORDERS&lt;/code&gt;, consisting of &lt;code&gt;ORDERLINES&lt;/code&gt;  linked to &lt;code&gt;PRODUCTS&lt;/code&gt;  as shown in the diagram below.&lt;/p&gt;




    
    
        
        
        
        
    

    
    
    

    
    




    
    
        
    


    

    
        &lt;p&gt;&lt;span class=&#34;image center-image&#34;&gt;
            &lt;img src=&#34;https://wattswhat.org/img/2015/01/100_rdbms-1024x653.png&#34; alt=&#34;RDBMS: ordering data model&#34; /&gt;
        &lt;/span&gt;&lt;/p&gt;
    



&lt;p&gt;Lets also assume we want to ask two questions of our data relating to the purchases of Raspberry Pi’s (product ID P4). We could write some SQL queries as shown below to query this data:&lt;/p&gt;




    
    
        
        
        
        
    

    
    
    

    
    




    
    
        
    


    

    
        &lt;p&gt;&lt;span class=&#34;image center-image&#34;&gt;
            &lt;img src=&#34;https://wattswhat.org/img/2015/01/sot_110_rdbms_query1and_2.png&#34; alt=&#34;RDBMS: SQL queries&#34; /&gt;
        &lt;/span&gt;&lt;/p&gt;
    



&lt;p&gt;Now not every NoSQL database is going to have some form of SQL sympathy built into its query language, and there are simply too many of them out there for us to compare them all. I shall therefore pick two that I have actively worked with to use as examples for my purposes. Lets see how Cassandra and Neo4j deal with the modelling and querying of this data with their respective query languages.&lt;/p&gt;

&lt;h2 id=&#34;cassandra-and-cql&#34;&gt;Cassandra and CQL&lt;/h2&gt;

&lt;p&gt;&lt;a href=&#34;http://cassandra.apache.org/&#34;&gt;Cassandra&lt;/a&gt; falls into the column family NoSQL camp with its “semi structured” format and is presently heavily pushing CQL (The Cassandra Query Language) as the recommended way of interacting with it’s underlying datastore.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Cassandra Query Language (CQL) is the default and primary interface into the Cassandra DBMS. Using CQL is similar to using SQL (Structured Query Language). CQL and SQL share the same abstract idea of a table constructed of columns and rows. The main difference from SQL is that Cassandra does not support joins or subqueries&amp;rdquo;
- &lt;a href=&#34;http://www.datastax.com/documentation/cassandra/2.1/cassandra/cql.html&#34;&gt;www.datastax.com/documentation/ cassandra/2.1/cassandra/cql.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For this example I am going to work backwards, i.e. first show you the CQL query statements which result in the same answers to the SQL queries used in the RDBMS example above, and then pick up on a few related discussion points.&lt;/p&gt;
&lt;div class=&#34;highlight&#34; style=&#34;background: #272822&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&#34;color: #75715e&#34;&gt;-- Num Raspberry Pi&amp;#39;s bought by each customer:&lt;/span&gt;
&lt;span style=&#34;color: #66d9ef&#34;&gt;SELECT&lt;/span&gt; &lt;span style=&#34;color: #f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color: #66d9ef&#34;&gt;FROM&lt;/span&gt; &lt;span style=&#34;color: #f8f8f2&#34;&gt;CustPurchByProduct&lt;/span&gt;
&lt;span style=&#34;color: #66d9ef&#34;&gt;WHERE&lt;/span&gt; &lt;span style=&#34;color: #f8f8f2&#34;&gt;productId&lt;/span&gt; &lt;span style=&#34;color: #f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color: #e6db74&#34;&gt;&amp;#39;P4&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;highlight&#34; style=&#34;background: #272822&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&#34;color: #75715e&#34;&gt;-- Total number of distinct users who bought Raspberry Pi&amp;#39;s  &lt;/span&gt;
&lt;span style=&#34;color: #66d9ef&#34;&gt;SELECT&lt;/span&gt; &lt;span style=&#34;color: #f8f8f2&#34;&gt;COUNT(&lt;/span&gt;&lt;span style=&#34;color: #f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color: #66d9ef&#34;&gt;FROM&lt;/span&gt; &lt;span style=&#34;color: #f8f8f2&#34;&gt;CustPurchByProduct&lt;/span&gt;
&lt;span style=&#34;color: #66d9ef&#34;&gt;WHERE&lt;/span&gt; &lt;span style=&#34;color: #f8f8f2&#34;&gt;productId&lt;/span&gt; &lt;span style=&#34;color: #f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color: #e6db74&#34;&gt;&amp;#39;P4&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Syntax looks quite similar to SQL, albeit the query seems scarily simple. So where are those SQL joins, what’s going on? As per the official philosophy, Cassandra does not really &lt;em&gt;do&lt;/em&gt; joins, rather you are actively encouraged to denormalize your data (i.e. don’t be afraid to write data multiple times if necessary) to answer different questions. In this case, you might decide to model your domain something as follows:&lt;/p&gt;




    

    
    




    
    
        
    


    

    &lt;div class=&#34;box alt&#34;&gt;
        &lt;div class=&#34;row uniform&#34;&gt;
        
        
        
            
                &lt;div class=&#34;12u&#34;&gt;
            
            
        
            
                
                    
                    &lt;span class=&#34;image fit&#34;&gt;
                
            
            
        
            
                
                        &lt;img src=&#39;https://wattswhat.org/img/2015/01/200_cql_setup-1024x696.png&#39;
                            alt=&#34;Cassandra: ordering data model&#34; /&gt;
                    &lt;/span&gt;&lt;/div&gt;
                
                
            
            
        
        &lt;/div&gt;
    &lt;/div&gt;



&lt;h4 id=&#34;each-table-is-an-island&#34;&gt;Each table is an island&lt;/h4&gt;

&lt;p&gt;OK, Cassandra does not do joins, and in this case we can see that a whole separate denormalized table (aka column-family in Cassandra) &lt;em&gt;CustPurchByProduct&lt;/em&gt;  was created to answer the two core questions posed.&lt;/p&gt;

&lt;p&gt;So in this case, the comparison is simple, the concept of SQL joins simply does not exist. You should never really expect to see any SQL join like syntax in CQL statements, and by implication, no foreign key references either – it simply does not compute in Cassandra.&lt;/p&gt;

&lt;h4 id=&#34;the-3-legged-table&#34;&gt;The 3 legged table&lt;/h4&gt;

&lt;p&gt;Leaving the joins and foreign keys aside, via the CQL shell (similar to SQL shell type programs), we gain some tabular insight into our data. The CQL &lt;code&gt;CREATE&lt;/code&gt; and &lt;code&gt;SELECT&lt;/code&gt; statements relating to &lt;strong&gt;Orders&lt;/strong&gt;  and &lt;strong&gt;Products&lt;/strong&gt;  column families seem to map very similarly to their RDBMS counterpart – tables, so far so good.&lt;/p&gt;

&lt;p&gt;Lets however take a closer look at &lt;strong&gt;OrderLines&lt;/strong&gt;. Firstly, what is interesting to note is that even though the CQL &lt;code&gt;SELECT&lt;/code&gt; queries appear to give the impression of bringing back four traditional RDBMS style rows with three columns (&lt;strong&gt;orderId&lt;/strong&gt;, &lt;strong&gt;productId&lt;/strong&gt;  and &lt;strong&gt;qty&lt;/strong&gt;), under the covers the story is quite different. The internal representation of the &lt;strong&gt;OrderLines&lt;/strong&gt; column family actually has two Cassandra partitions (think rows) with a variable number of columns. You can think of a partition (and in fact this is how the underlying storage engine would represent it) as a very wide row in an RDBMS; one that has no fixed set of columns, but rather the columns are dynamically created based on the table definition, &lt;em&gt;and&lt;/em&gt; the actual data stored. In our example &lt;strong&gt;P1:qty&lt;/strong&gt;, &lt;strong&gt;P2:qty&lt;/strong&gt;  and &lt;strong&gt;P4:qty&lt;/strong&gt;  are the effective column names, with the only value stored as a table cell being the &lt;strong&gt;qty&lt;/strong&gt; itself. This is an example of Cassandra ensuring that CQL can use the full potential of the underlying storage engine – one of Cassandra’s key strengths, whilst at the same time, giving users an easier way of defining and visualising the data, closer to the way in which a more traditional RDBMS developer might expect to see/reason about it.&lt;/p&gt;

&lt;p&gt;This RDBMS column mismatch phenomenon is also highlighted when looking at the CQL &lt;code&gt;CREATE&lt;/code&gt; statement for &lt;strong&gt;OrderLines&lt;/strong&gt; and &lt;strong&gt;CustPurchByProduct&lt;/strong&gt;. Although they look very similar to SQL &lt;code&gt;CREATE&lt;/code&gt; statements, they do not translate into a 1-to-1 mapping of physical column names in the traditional RDBMS. In this case a pivot like transformation is performed on the fly, both when the data is initially presented/inserted, as well as queried via CQL. This way CQL ensures that the transformation between what is logically defined and presented to the user, and the physical representation, is kept in sync for both the &lt;code&gt;CREATE&lt;/code&gt; and &lt;code&gt;SELECT&lt;/code&gt; statements, so ultimately, the two move together.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;SideNote:&lt;/strong&gt; The &lt;strong&gt;OrderLines&lt;/strong&gt; column family is actually a little thin. In reality, this column family would more than likely have a few extra columns, something along the lines of what is shown in the diagram below. Again, this is because there are no joins and Cassandra actively encourages you to denormalize your data. For the purposes of this blog entry however, it has deliberately been kept thin to allow for an easier comparison with the alternative options. &lt;strong&gt;CustPurchByProduct&lt;/strong&gt; probably falls into the same category too.&lt;/p&gt;
&lt;/blockquote&gt;




    
    
        
        
        
        
    

    
    
    

    
    




    
    
        
    


    

    
        &lt;p&gt;&lt;span class=&#34;image center-image&#34;&gt;
            &lt;img src=&#34;https://wattswhat.org/img/2015/01/210_cql_orderlinesfull1-1024x392.png&#34; alt=&#34;Cassandra: Fuller OrderLine table sample&#34; /&gt;
        &lt;/span&gt;&lt;/p&gt;
    



&lt;h4 id=&#34;to-be-or-not-to-be-that-is-the-question&#34;&gt;To be, or not to be - that is the question&lt;/h4&gt;

&lt;p&gt;Another thing which tends to confuse newcomers to Cassandra, is that a  &lt;code&gt;PRIMARY KEY&lt;/code&gt; definition in CQL, is not treated in the same way as a that for an RDBMS.&lt;/p&gt;

&lt;p&gt;Firstly lets examine this from the perspective of the data model and storage perspective. If you look closely at the CQL &lt;code&gt;CREATE&lt;/code&gt; statement for the &lt;strong&gt;CustPurchByProduct&lt;/strong&gt; column family, and what this physically translates to under the covers, you will see that the first part of the SQL looking compound primary key (&lt;strong&gt;productId&lt;/strong&gt;) was used as the row key (also referred to as a partition key in Cassandra). The remaining column &lt;strong&gt;customerId&lt;/strong&gt; (in Cassandra terminology also referred to as a clustering key) actually got its value‘s absorbed into the various column headings itself (&lt;strong&gt;C1:cnt&lt;/strong&gt;, &lt;strong&gt;C2:cnt&lt;/strong&gt;)! Not quite what you might have been expecting.&lt;/p&gt;

&lt;p&gt;Secondly, you would expect a primary key to ensure that you only have one unique record in the database for a given key, can we at least rely on this? The answer is &lt;em&gt;Yes but…&lt;/em&gt; Cassandra will indeed ensure that there is only one reference to a combination of a primary key, however Cassandra tends to treat both its  &lt;code&gt;INSERT&lt;/code&gt; and &lt;code&gt;UPDATE&lt;/code&gt; statements as ‘Add or update’. In other words, having already inserted a record with primary key X, you could call that exact same statement again and it would not throw a “Primary Key Already Exists” type exception, rather, it would simply update the existing row. Likewise you could call &lt;code&gt;UPDATE&lt;/code&gt; with data which does not exist and it would merely insert it the first time and update it thereafter.&lt;/p&gt;

&lt;p&gt;The point here is that a &lt;code&gt;PRIMARY KEY&lt;/code&gt; as used in CQL is not an exact 1-to-1 logical mapping to its counterpart used in SQL.&lt;/p&gt;

&lt;h4 id=&#34;cassandra-wrap-up&#34;&gt;Cassandra wrap up …&lt;/h4&gt;

&lt;p&gt;There is much more which could be said about the specifics of Cassandra data modelling, however as the point of this particular blog post is more to highlight how NoSQL query languages translate/compare to SQL, and not what the merits and demerits of particular stores and data modelling approaches are, we shall leave this example here. Perhaps a dedicated blog on specific DB comparisons could be next on the cards. In any case, we now move on to look at Neo4j.&lt;/p&gt;

&lt;h1 id=&#34;neo4j-and-cypher&#34;&gt;Neo4j and Cypher&lt;/h1&gt;

&lt;p&gt;&lt;a href=&#34;http://neo4j.com/&#34;&gt;Neo4j&lt;/a&gt; is a graph database, where its sweet spot is getting answers about highly connected data. With a graph, you tend not so much to &lt;em&gt;query&lt;/em&gt; vast swathes of its total structure, as you do start somewhere and then &lt;em&gt;traverse&lt;/em&gt; it, gathering info along the way. Cypher has evolved as Neo4j’s humane graph query language.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Cypher is inspired by a number of different approaches and builds upon established practices for expressive querying. Most of the keywords like WHERE and ORDER BY are inspired by SQL. Pattern matching borrows expression approaches from SPARQL…. Cypher borrows it structure from SQL — queries are built up using various clauses.&amp;rdquo;
– &lt;a href=&#34;http://neo4j.com/docs/stable/cypher-introduction.html&#34;&gt;http://neo4j.com/docs/stable/cypher-introduction.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once again lets work backwards from the Cypher query and creation statements which roughly equate to the RDBMS counterparts originally shown and then discuss a few points.&lt;/p&gt;
&lt;div class=&#34;highlight&#34; style=&#34;background: #272822&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&#34;color: #75715e&#34;&gt;// Num Raspberry Pi&amp;#39;s bought by each customer&lt;/span&gt;
&lt;span style=&#34;color: #66d9ef&#34;&gt;MATCH&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;  (o:&lt;/span&gt;&lt;span style=&#34;color: #66d9ef&#34;&gt;Order&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color: #f92672&#34;&gt;-[&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;r:HAS_ORDER_ITEM&lt;/span&gt;&lt;span style=&#34;color: #f92672&#34;&gt;]-&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;(p:Product)&lt;/span&gt;
&lt;span style=&#34;color: #66d9ef&#34;&gt;WHERE&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;   p.prodId = &lt;/span&gt;&lt;span style=&#34;color: #960050; background-color: #1e0010&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;P4&lt;/span&gt;&lt;span style=&#34;color: #960050; background-color: #1e0010&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color: #66d9ef&#34;&gt;RETURN&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;  o.custId, sum(r.qty)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;highlight&#34; style=&#34;background: #272822&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&#34;color: #75715e&#34;&gt;// Total number of distinct users who bought Raspberry Pi&amp;#39;s  &lt;/span&gt;
&lt;span style=&#34;color: #66d9ef&#34;&gt;MATCH&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;  (o:&lt;/span&gt;&lt;span style=&#34;color: #66d9ef&#34;&gt;Order&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color: #f92672&#34;&gt;-[&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;:HAS_ORDER_ITEM&lt;/span&gt;&lt;span style=&#34;color: #f92672&#34;&gt;]-&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;(p:Product)&lt;/span&gt;
&lt;span style=&#34;color: #66d9ef&#34;&gt;WHERE&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;   p.prodId = &lt;/span&gt;&lt;span style=&#34;color: #960050; background-color: #1e0010&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;P4&lt;/span&gt;&lt;span style=&#34;color: #960050; background-color: #1e0010&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color: #66d9ef&#34;&gt;RETURN&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;  count( &lt;/span&gt;&lt;span style=&#34;color: #66d9ef&#34;&gt;distinct&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt; o.custId )&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Hhhm, &lt;em&gt;some&lt;/em&gt; aspects looks similar to SQL, and others very much not. The &lt;code&gt;MATCH&lt;/code&gt; statement is obviously quite unique. The &lt;code&gt;WHERE&lt;/code&gt; clause gives us a slightly warmer feeling of familiarity and &lt;code&gt;RETURN&lt;/code&gt; looks (ish) like a SQL &lt;code&gt;SELECT&lt;/code&gt; but slapped onto the end. There also appears to be some familiar looking &lt;code&gt;count&lt;/code&gt; and &lt;code&gt;distinct&lt;/code&gt; functions. So how does Neo4j model and create data for this scenario, and what does it look like under the covers?&lt;/p&gt;




    
    
        
        
        
        
    

    
    
    

    
    




    
    
        
    


    

    
        &lt;p&gt;&lt;span class=&#34;image center-image&#34;&gt;
            &lt;img src=&#34;https://wattswhat.org/img/2015/01/300_neo4j_setup.png&#34; alt=&#34;Neo4j: ordering data model&#34; /&gt;
        &lt;/span&gt;&lt;/p&gt;
    



&lt;p&gt;As with CQL, Neo4j also provides a shell whereby we can try out our queries and statements to gain some tabular insight into our data. We shall also be using this as shown in the diagrams below.&lt;/p&gt;

&lt;p&gt;I should at this stage point out that Neo4j was a wonderful graph visualisation tool via the Neo4j console available for seeing visual  “connections” however as we are comparing SQL, so we shall also use its shell program.&lt;/p&gt;

&lt;h4 id=&#34;eat-on-your-lap-no-table-required&#34;&gt;Eat on your lap – no table required&lt;/h4&gt;

&lt;p&gt;At its heart, Neo4j is a property based graph DB, consisting simply of nodes and relationships. Nodes of the same type can be grouped together using something called a “Label” – roughly equated to the way a table groups the same types of records in an RDBMS, except that there is no traditional schema per so – i.e. no restrictions on which properties (columns) the node (table ish) can contain. So in our example, although at present all of the &lt;strong&gt;Order&lt;/strong&gt; nodes have three properties, this does not restrict us from adding another property, say a &lt;strong&gt;poNumber&lt;/strong&gt; to new &lt;strong&gt;Order&lt;/strong&gt; nodes created in the future – without affecting any of the previous ones. Neo4j is officially schema-optional as there are some forms of constraints (e.g. creating a genuinely unique key) and indexes which can be applied to your model. However, as far as defining for example that a &lt;strong&gt;User&lt;/strong&gt; node will always have a &lt;strong&gt;name&lt;/strong&gt; and an &lt;strong&gt;age&lt;/strong&gt; attribute – that level of schema definition cannot be enforced out of the box at present.&lt;/p&gt;

&lt;h4 id=&#34;join-the-dots-to-make-the-connection&#34;&gt;Join the dots to make the connection …&lt;/h4&gt;

&lt;p&gt;Unlike Cassandra which goes for a denormalized approach, graphs are at the other end of the NoSQL spectrum. Being all about connected data, nodes are indeed able to be &lt;em&gt;joined&lt;/em&gt; to each other and this is done via the first class Neo4j relationship concept. When it comes to querying or traversing the graph however, this joining is expressed rather as a pattern match. For example the generic “find me all orders with at least one product (orderItem)” is expressed in the ascii art syntax of &lt;code&gt;MATCH (:Order)-[:HAS_ORDER_ITEM]-(:Product)&lt;/code&gt;. In general with a graph you would typically look to constrain your query a bit more i.e. “find me all orders which contain the P4 product ” is expressed as:&lt;/p&gt;
&lt;div class=&#34;highlight&#34; style=&#34;background: #272822&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&#34;color: #66d9ef&#34;&gt;MATCH&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt; (o:&lt;/span&gt;&lt;span style=&#34;color: #66d9ef&#34;&gt;Order&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color: #f92672&#34;&gt;-[&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;:HAS_ORDER_ITEM&lt;/span&gt;&lt;span style=&#34;color: #f92672&#34;&gt;]-&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;(p:Product)&lt;/span&gt;
&lt;span style=&#34;color: #66d9ef&#34;&gt;WHERE&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt; p.prodId = &lt;/span&gt;&lt;span style=&#34;color: #960050; background-color: #1e0010&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt;P4&lt;/span&gt;&lt;span style=&#34;color: #960050; background-color: #1e0010&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #66d9ef&#34;&gt;return&lt;/span&gt;&lt;span style=&#34;color: #f8f8f2&#34;&gt; o.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now this does look fundamentally different to any SQL you’ve seen. However, if you can get your head around the fact that the &lt;code&gt;MATCH&lt;/code&gt; bits are “roughly” the join part, then the remaining syntax is more easily digested with things like &lt;code&gt;WHERE&lt;/code&gt; clauses, count and distinct functions etc.&lt;/p&gt;

&lt;p&gt;In an effort to make the Cypher language more “whiteboard friendly”, as well as try and expose and convey the underlying native graph structure inherent in the queries been undertaken, the Neo4j Cypher language designers explicitly opted for making pattern matching central, rather than opting for the more familiar, yet potentially more verbose standard SQL join like syntax. In order to help SQL thinkers jump this divide however, Neo4j provides a dedicated &lt;a href=&#34;http://neo4j.com/docs/stable/examples-from-sql-to-cypher.html&#34;&gt;From SQL to Cypher&lt;/a&gt; section on the official Neo4j website.&lt;/p&gt;

&lt;p&gt;Interestingly enough, &lt;a href=&#34;http://www.orientechnologies.com/orientdb/&#34;&gt;OrientDB&lt;/a&gt;, which also operates in the graph (and document) database space have taken a slightly different stance. Disclaimer: I do not have commercial experience with OrientDB. From their website:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;… Instead of inventing “Yet Another Query Language”, we started from the widely used and well understood SQL. We then extended it to support more complex graph concepts like Trees and Graphs. Why SQL? SQL ubiquitous in the database developer world, it is familiar …&amp;rdquo; - [&lt;a href=&#34;http://www.orientechnologies.com/docs/2.0/orientdb.wiki/Tutorial-SQL.html]http://www.orientechnologies.com/docs/2.0/orientdb.wiki/Tutorial-SQL.html&#34;&gt;http://www.orientechnologies.com/docs/2.0/orientdb.wiki/Tutorial-SQL.html]http://www.orientechnologies.com/docs/2.0/orientdb.wiki/Tutorial-SQL.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However in OrientDB’s version of SQL, as with Cypher, the choice was taken not to make use of the traditional SQL join syntax, instead opting for using a dot (.) notation[1] to navigate its relationships (referred to as links) instead. So even though its starting point is SQL, it too has chosen to deviate from using the standard SQL join syntax in order to better exploit the underlying data structure.&lt;/p&gt;

&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;

&lt;h3 id=&#34;via-an-analogy&#34;&gt;Via an analogy …&lt;/h3&gt;

&lt;p&gt;So you are a ‘box drawing expert’. You have however been using standard pens all your life for drawing boxes, and now you have been asked to draw a box using a new pen, which you are told, is specifically aimed at drawing boxes in a ‘new and shiny way’. So armed with your previous box drawing knowledge and experience, you set out on your task. Well how hard can it be you say. You know how to use a pen, you even have a trusted old favourite which you bring out for special occasions. This new pen probably just does some fancy highlighting or something, but at the end of the day if it looks like a pen, and writes like a pen, it’s probably still just a pen. You finish your box drawing exercise, and well, it does sort of look like the boxes you usually draw, maybe a little bit more messy than you were expecting, but hey, this must be how all the new kids are doing it, and it’s probably just what ‘new and shiny box world’ looks like.&lt;/p&gt;




    
    
        
        
        
        
    

    
    
    

    
    




    
    
        
    


    

    
        &lt;p&gt;&lt;span class=&#34;image center-image&#34;&gt;
            &lt;img src=&#34;https://wattswhat.org/img/2015/01/2d_small_box.png&#34; alt=&#34;3D box drawn with a 2D mindset&#34; /&gt;
        &lt;/span&gt;&lt;/p&gt;
    



&lt;p&gt;Problem is, the pen you were given was actually a 3D doodling pen[2]. Yes it’s a sort of a pen, however it is not really meant for drawing in a 2D world, but rather a 3D one. Because however you were comfortable in applying your 2D way of thinking to the task at hand, you simply started by drawing your box in this mindset. If however, you understand that actually this 3D pen is capable of more than simply mimicking what can be done in a 2D world, your box may instead have turned out like this:&lt;/p&gt;




    
    
        
        
        
        
    

    
    
    

    
    




    
    
        
    


    

    
        &lt;p&gt;&lt;span class=&#34;image center-image&#34;&gt;
            &lt;img src=&#34;https://wattswhat.org/img/2015/01/3d_doodle_box_small.jpg&#34; alt=&#34;3D box drawn with 3D mindset (via a doodle pen)&#34; /&gt;
        &lt;/span&gt;&lt;/p&gt;
    



&lt;h3 id=&#34;via-conventional-words&#34;&gt;Via conventional words …&lt;/h3&gt;

&lt;p&gt;So yes, it appears some NoSQL vendors have “somewhat” adapted their querying languages, to a larger or lesser degree, to be more sympathetic towards some SQL like syntax and concepts. The fundamental differences in underlying data structures however, mean that this is never going to be a perfect fit and it is worth bearing this in mind when trying to use them.&lt;/p&gt;

&lt;p&gt;Query languages and approaches to try and help people adapt/transition into new ways of thinking by comparing or making aspects of the query language seem familiar can be very helpful in some instances. However, as has been demonstrated in this blog, this can sometimes be confusing, especially if your background means you expect the &lt;em&gt;semantics&lt;/em&gt; behind statements, and not merely the &lt;em&gt;usage&lt;/em&gt; of common terminology, to operate in the same way as SQL. I would therefore urge caution in simply skimming the surface when engaging in these technologies and &lt;em&gt;only&lt;/em&gt; thinking in your current (SQL) mindset, as you may fundamentally miss out on leveraging the best parts of your underlying datastore if you do, or even worse, design your model incorrectly in the first place as a result.&lt;/p&gt;

&lt;p&gt;Can a language or database be all things to all people at the same time? Probably not. When it comes to trying to get to grips with a new kind of datastore, I feel that trying to gain some &lt;a href=&#34;http://mechanical-sympathy.blogspot.co.uk/2011/07/why-mechanical-sympathy.html&#34;&gt;mechanical sympathy&lt;/a&gt; for your new datastore can go a long way to helping you understand it, as well as effectively being able to use it, regardless of what query language is being used; be that SQL like, a hybrid, or something completely different.&lt;/p&gt;

&lt;p&gt;[1] OrientDB uses the “dot (.) notation” to navigate LINKS.” – &lt;a href=&#34;https://github.com/orientechnologies/orientdb/wiki/SQL&#34;&gt;https://github.com/orientechnologies/orientdb/wiki/SQL&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[2] The 3D doodling pen is actually a real thing, and well it looks pretty impressive to be honest. Here is a link in case you are interested: &lt;a href=&#34;http://www.makerstechnology.com/3doodler-3d-creativity-pen&#34;&gt;http://www.makerstechnology.com/3doodler-3d-creativity-pen&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Life’s a journey, learn from the ride</title>
      <link>https://wattswhat.org/2015/01/lifes-a-journey-learn-from-the-ride/</link>
      <pubDate>Mon, 12 Jan 2015 00:00:00 +0000</pubDate>
      
      <guid>https://wattswhat.org/2015/01/lifes-a-journey-learn-from-the-ride/</guid>
      <description>

&lt;p&gt;Over my years of consulting and working with people, building, and developing stuff, I have inevitably built up some views over what I feel works, what doesn’t, and, more often than not, come to understand that things don’t quite work in the way I thought they did!&lt;/p&gt;

&lt;p&gt;Initially centred around tech and development, but evolving to include general life lessons as well, I decided to share some of my realisations in the form of some short and sweet, value-based resolution statements for this inaugural post. If you are reading this and you are not from a techie background, then some of the statements may not make much sense – apologies for this but this did actually start as a technical post first! Feel free to skip to the end if you simply want to see the statements, or carry on if you are interested in the background on how I arrived at them.&lt;/p&gt;

&lt;p&gt;One of my 2015 new years resolutions was to stop procrastinating and actually get my blog site up and running. Better late than never, and tick for me – this one is now done :) However, I sometimes find that new years resolutions tend to focus on a single narrow particular outcome. One of the lessons I have learned is that more often than not, the value is in the journey itself, where hidden gems (not Ruby) and underlying principles are there to be mined and extracted if you look carefully – often yielding more fruit than the single end outcome itself.&lt;/p&gt;

&lt;p&gt;So, below is a short and sweet, A-Z listing of some of my value resolution statements laid out in a manner not dissimilar to that of the original &lt;a href=&#34;http://agilemanifesto.org/&#34;&gt;agile manifesto&lt;/a&gt;. As per the &lt;em&gt;spirit&lt;/em&gt; (but not necessarily the implementations) of the agile manifesto, it is not to say that things on the right are not important, but rather, through time and experience, I see evidence of those on the left bearing better fruit and value in the long run. And of course in the &lt;em&gt;spirit&lt;/em&gt; of agile, I reserve the right to change my mind as I learn and discover more! So without further ado:&lt;/p&gt;

&lt;h3 id=&#34;life-s-a-journey-and-thus-far-on-my-ride-i-have-come-to-value&#34;&gt;Life’s a journey, and thus far on my ride, I have come to value:&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Automated Testing&lt;/strong&gt; over Ad-hoc testing&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Building Bridges&lt;/strong&gt; over Building empires&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Challenging&lt;/strong&gt; over Conforming

&lt;ul&gt;
&lt;li&gt;There is a reason why square pegs do not fit in round holes&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data Consistency (eventually)&lt;/strong&gt; over Data Cleansing

&lt;ul&gt;
&lt;li&gt;Think before you drink your data, as it may have bad consequences for you later down the line otherwise&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Engaging&lt;/strong&gt; over Emailing&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Face-to-face friends&lt;/strong&gt; over Facebook friends&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Guiding&lt;/strong&gt; over Guarding

&lt;ul&gt;
&lt;li&gt;Being taught how to navigate a situation is immensly more beneficial than being prevented from ever making a mistake and not being able to learn from it&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Holistic teams&lt;/strong&gt; over Hand-offs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Integrity&lt;/strong&gt; over Intellect&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Jumping in&lt;/strong&gt; over Jumping out

&lt;ul&gt;
&lt;li&gt;When the going gets tough, the tough will jump in, rather than out, to help&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Knowing how something works under the covers&lt;/strong&gt; over Knowing how to merely operate it&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Load Balancing&lt;/strong&gt; over Load shedding

&lt;ul&gt;
&lt;li&gt;Inspired by a recent trip to South Africa, but the general principle remains – do something before its too late and drastic action needs to be taken!&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mentoring&lt;/strong&gt; over Managing&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nurture&lt;/strong&gt; over Nature

&lt;ul&gt;
&lt;li&gt;Relying on raw talent alone will only take you so far, but hard graft and access to a good mentor can often take you further&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Offer&lt;/strong&gt; over Obligation

&lt;ul&gt;
&lt;li&gt;Offer yourself or your services before it is asked or demanded of you&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Proposed ideas&lt;/strong&gt; over (waiting for) Perfectly thought out ones

&lt;ul&gt;
&lt;li&gt;Ideas are seldom right when you first start out, but its generally only by sharing and bouncing them off others that they become well formed&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Questioning&lt;/strong&gt; over Quietly trying to work out what’s going on by yourself for hours&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Re-use&lt;/strong&gt; over Re-invent&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Simplicity&lt;/strong&gt; over Smart and super cool, but complex

&lt;ul&gt;
&lt;li&gt;My own personal motto is “Strive for simple when you can, be pragmatic when you can’t”&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Teaching&lt;/strong&gt; over Telling&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Uniqueness&lt;/strong&gt; over Uniformity (when innovating) BUT&lt;br /&gt;
&lt;strong&gt;Uniformity&lt;/strong&gt; over Uniqueness (when maintaining)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Viral&lt;/strong&gt; over Virus

&lt;ul&gt;
&lt;li&gt;Make an impact, but just ensure it’s a positive one!&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wisdom&lt;/strong&gt; over Wealth&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;X-Factor&lt;/strong&gt; over X

&lt;ul&gt;
&lt;li&gt;Because sometimes it takes something uniquely different, or someone with that unique perspective, to be able to shift you from your default position&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You as-you-are&lt;/strong&gt; over Yet-another-clone&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ZX Spectrum&lt;/strong&gt; over all other 1980’s personal home computers

&lt;ul&gt;
&lt;li&gt;Z is not an easy letter to find comparisons for, and well, as the ZX Spectrum was my first computer which helped usher in my tech beginnings, and, valuing challenging over conforming to the status quo, I break from my own self imposed format and give it a special mention!&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
  </channel>
</rss>