<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Sql on traviscj/blog</title>
    <link>https://traviscj.com/blog/tags/sql/</link>
    <description>Recent content in Sql on traviscj/blog</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Tue, 11 Jun 2019 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://traviscj.com/blog/tags/sql/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>feeds justification</title>
      <link>https://traviscj.com/blog/post/2019-06-11-feeds_justification/</link>
      <pubDate>Tue, 11 Jun 2019 00:00:00 +0000</pubDate>
      <guid>https://traviscj.com/blog/post/2019-06-11-feeds_justification/</guid>
      <description>&lt;p&gt;I realized I&amp;rsquo;ve left out a major part from my &lt;a href=&#34;https://traviscj.com/blog/post/2019-01-08-feed_sequences/&#34;&gt;sequence&lt;/a&gt; of &lt;a href=&#34;https://traviscj.com/blog/post/2018-10-03-feeds_as_cache_invalidation_mechanism/&#34;&gt;previous&lt;/a&gt; &lt;a href=&#34;https://traviscj.com/blog/post/2018-06-29-mysql_feeds/&#34;&gt;feed&lt;/a&gt;-&lt;a href=&#34;https://traviscj.com/blog/post/2018-07-10-cross-dc-sync-with-feed-published_kv/&#34;&gt;related&lt;/a&gt; &lt;a href=&#34;https://traviscj.com/blog/post/2018-10-29-sharded_feeds/&#34;&gt;posts&lt;/a&gt;: a justification for why we should bother with a separate &lt;code&gt;feed_sync_id&lt;/code&gt;.&#xA;So let&amp;rsquo;s give it a shot!&#xA;The fundamental problem is:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;code&gt;AUTO_INCREMENT&lt;/code&gt; ids are &lt;em&gt;assigned&lt;/em&gt; in &lt;strong&gt;insertion&lt;/strong&gt; order, but become visible to other threads in &lt;strong&gt;commit&lt;/strong&gt; order.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;To see how this causes a problem, consider the interactions and visibilities between three transactions to the same database:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;t0: TRX0: BEGIN; INSERT INTO kv (ns, k, v) VALUES (&amp;quot;-&amp;quot;, &amp;quot;k0&amp;quot;, &amp;quot;v0&amp;quot;); COMMIT;&#xA;t1: TRX1: BEGIN; INSERT INTO kv (ns, k, v) VALUES (&amp;quot;-&amp;quot;, &amp;quot;k1&amp;quot;, &amp;quot;v1&amp;quot;);&#xA;t2: TRX2: BEGIN; INSERT INTO kv (ns, k, v) VALUES (&amp;quot;-&amp;quot;, &amp;quot;k2&amp;quot;, &amp;quot;v2&amp;quot;);&#xA;t3: TRX0: SELECT MAX(id) FROM kv;&#xA;t4: TRX2: COMMIT;&#xA;t5: TRX0: SELECT MAX(id) FROM kv;&#xA;t6: TRX1: COMMIT;&#xA;t7: TRX0: SELECT MAX(id) FROM kv;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Here, we have two transactions that both insert a new &lt;code&gt;kv&lt;/code&gt; record.&#xA;The database &lt;em&gt;has&lt;/em&gt; to assign an &lt;code&gt;id&lt;/code&gt; value to each of those records, because we might be creating other associations to those records in our application code.&#xA;But other threads &amp;ndash; &lt;code&gt;TRX0&lt;/code&gt; in this case &amp;ndash; shouldn&amp;rsquo;t be able to see those records until we &lt;code&gt;COMMIT&lt;/code&gt;, and so indeed the &lt;code&gt;SELECT&lt;/code&gt; at &lt;code&gt;t=t3&lt;/code&gt; might return &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>absolutely minimal OLTP to OLAP pipeline</title>
      <link>https://traviscj.com/blog/post/2019-04-25-oltp_to_olap/</link>
      <pubDate>Thu, 25 Apr 2019 00:00:00 +0000</pubDate>
      <guid>https://traviscj.com/blog/post/2019-04-25-oltp_to_olap/</guid>
      <description>&lt;p&gt;Suppose we have some data in a production OLTP database, and we need to send it to some OLAP database.&#xA;This post describes one of the simplest approaches, and how to make it productional enough to rely on.&lt;/p&gt;&#xA;&lt;p&gt;For every table &lt;code&gt;t&lt;/code&gt;, we need to:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;introduce a new field, &lt;code&gt;updated_at&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;introduce a new index on that field, so we can get the records that changed after a certain &lt;code&gt;updated_at&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;For example,&lt;/p&gt;</description>
    </item>
    <item>
      <title>feed sequences</title>
      <link>https://traviscj.com/blog/post/2019-01-08-feed_sequences/</link>
      <pubDate>Tue, 08 Jan 2019 00:00:00 +0000</pubDate>
      <guid>https://traviscj.com/blog/post/2019-01-08-feed_sequences/</guid>
      <description>&lt;p&gt;In the &lt;a href=&#34;https://traviscj.com/blog/post/2018-06-29-mysql_feeds/&#34;&gt;mysql feeds&lt;/a&gt; post, I mentioned that the publisher could do&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;MAX&lt;/span&gt;(feed_sync_id)&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; kv&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;to find the next &lt;code&gt;feed_sync_id&lt;/code&gt; during the publishing process, but&#xA;&lt;strong&gt;this is actually a really bad idea.&lt;/strong&gt;&#xA;(And I knew it at the time, so forgive me for selling lies&amp;hellip;)&lt;/p&gt;&#xA;&lt;h2 id=&#34;republishing&#34;&gt;Republishing&lt;/h2&gt;&#xA;&lt;p&gt;Before we jump into the problematic scenario, I&amp;rsquo;d like to motivate it with a tiny bit of background.&lt;/p&gt;&#xA;&lt;p&gt;The &lt;em&gt;republish&lt;/em&gt; operation is extremely useful when consumers need to receive updates.&#xA;It is also extremely simple!&#xA;A query like&lt;/p&gt;</description>
    </item>
    <item>
      <title>unreasonable wish -- an sql interface to websites</title>
      <link>https://traviscj.com/blog/post/2019-01-06-sql_interface_to_websites/</link>
      <pubDate>Sun, 06 Jan 2019 00:00:00 +0000</pubDate>
      <guid>https://traviscj.com/blog/post/2019-01-06-sql_interface_to_websites/</guid>
      <description>&lt;p&gt;I was searching Amazon Prime for some Earl Grey tea for my wife.&#xA;I got these results&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://traviscj.com/blog/assets/earl_grey_tea.png&#34; alt=&#34;earl grey tea&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;This was just a basic search for &lt;a href=&#34;https://www.amazon.com/s?url=srs%3D7301146011%26search-alias%3Dpantry&amp;amp;field-keywords=earl+grey+tea&#34;&gt;earl grey tea&lt;/a&gt; in the Prime Pantry store.&lt;/p&gt;&#xA;&lt;p&gt;I would love to&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&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;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; products p&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;WHERE&lt;/span&gt; p.prime_pantry &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;AND&lt;/span&gt; p.keywords &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;earl grey tea&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;AND&lt;/span&gt; p.packaging &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;bulk&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I get that this&amp;rsquo;ll never happen, but man&amp;hellip; it&amp;rsquo;d be nice.&lt;/p&gt;</description>
    </item>
    <item>
      <title>watching progress in mysql</title>
      <link>https://traviscj.com/blog/post/2019-01-04-watching_progress_in_mysql/</link>
      <pubDate>Fri, 04 Jan 2019 00:00:00 +0000</pubDate>
      <guid>https://traviscj.com/blog/post/2019-01-04-watching_progress_in_mysql/</guid>
      <description>&lt;p&gt;Pretty frequently at work, I end up &lt;a href=&#34;https://traviscj.com/blog/post/2014-10-15-dont_poll/&#34;&gt;polling&lt;/a&gt; a database with some command like&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;MAX&lt;/span&gt;(id) &lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; my_tbl;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;MAX&lt;/span&gt;(id) &lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; my_tbl;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;MAX&lt;/span&gt;(id) &lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; my_tbl;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;MAX&lt;/span&gt;(id) &lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; my_tbl;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- .... ad nauseam ....&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;ve eventually noticed a few patterns I use pretty consistently:&lt;/p&gt;&#xA;&lt;h3 id=&#34;estimate-eta-by-including-nowunix_timestamp&#34;&gt;estimate ETA by including &lt;code&gt;NOW()&lt;/code&gt;/&lt;code&gt;UNIX_TIMESTAMP()&lt;/code&gt;&lt;/h3&gt;&#xA;&lt;p&gt;Generally, the point of hovering over the table is to get an estimate of when it will finish/catch up/whatever.&#xA;For that, you generally want to include a timestamp in the query output, so when you come back a while later, you can know exactly how much time has elapsed.&#xA;I might transform the above query into&lt;/p&gt;</description>
    </item>
    <item>
      <title>sharded feeds</title>
      <link>https://traviscj.com/blog/post/2018-10-29-sharded_feeds/</link>
      <pubDate>Mon, 29 Oct 2018 18:30:00 +0000</pubDate>
      <guid>https://traviscj.com/blog/post/2018-10-29-sharded_feeds/</guid>
      <description>&lt;p&gt;Suppose that:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;our humble &lt;a href=&#34;https://traviscj.com/blog/post/2018-06-29-mysql_feeds/&#34;&gt;KV feed&lt;/a&gt; sees &lt;em&gt;a lot&lt;/em&gt; of traffic.&lt;/li&gt;&#xA;&lt;li&gt;someone needs to consume our &lt;a href=&#34;https://traviscj.com/blog/post/2018-06-29-mysql_feeds/&#34;&gt;KV feed&lt;/a&gt; with multiple threads.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;data&#34;&gt;data&lt;/h3&gt;&#xA;&lt;p&gt;The first step is to introduce a notion of &amp;ldquo;shards&amp;rdquo; into our data model:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;ALTER&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt;kv&lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;ADD&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;COLUMN&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt;shard&lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt; INT(&lt;span style=&#34;color:#ae81ff&#34;&gt;11&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;DEFAULT&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;0&amp;#39;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;ADD&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;INDEX&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt;k_fsi_s&lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt;feed_sync_id&lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt;shard&lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;publishing&#34;&gt;publishing&lt;/h3&gt;&#xA;&lt;p&gt;We don&amp;rsquo;t need to alter the publishing until the publishing &lt;em&gt;itself&lt;/em&gt; is too slow to work with a single thread, but this introduces a &lt;em&gt;lot&lt;/em&gt; of complications, so let&amp;rsquo;s just hold off for now.&lt;/p&gt;</description>
    </item>
    <item>
      <title>history preserving data models</title>
      <link>https://traviscj.com/blog/post/2018-07-02-history-preserving-data-models/</link>
      <pubDate>Mon, 02 Jul 2018 11:34:39 +0000</pubDate>
      <guid>https://traviscj.com/blog/post/2018-07-02-history-preserving-data-models/</guid>
      <description>&lt;p&gt;Start with a super simple data model:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;CREATE TABLE kv (&#xA;  id BIGINT(22) NOT NULL AUTO_INCREMENT,&#xA;  k VARCHAR(255) NOT NULL,&#xA;  v LONGBLOB NOT NULL,&#xA;  PRIMARY KEY (`id`),&#xA;  UNIQUE KEY u_k (`k`)&#xA;) Engine=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Suppose we want to audit &amp;ldquo;changes&amp;rdquo; to this data model.&lt;/p&gt;&#xA;&lt;h2 id=&#34;approach-1-kv_log&#34;&gt;Approach 1: &lt;code&gt;kv_log&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;p&gt;add data model like&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;CREATE TABLE `kv_log` (&#xA;  id BIGINT(22) NOT NULL AUTO_INCREMENT,&#xA;  changed_at TIMESTAMP NOT NULL,&#xA;  k VARCHAR(255) NOT NULL,&#xA;  old_v LONGBLOB NOT NULL,&#xA;  new_v LONGBLOB NOT NULL,&#xA;  &#xA;)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;current value query: unchanged&lt;/p&gt;</description>
    </item>
    <item>
      <title>mysql feeds</title>
      <link>https://traviscj.com/blog/post/2018-06-29-mysql_feeds/</link>
      <pubDate>Fri, 29 Jun 2018 00:00:00 +0000</pubDate>
      <guid>https://traviscj.com/blog/post/2018-06-29-mysql_feeds/</guid>
      <description>&lt;p&gt;At work, we use a pattern called &lt;em&gt;feeds&lt;/em&gt; that gets an incredible amount of work done.&#xA;I&amp;rsquo;ve been wanting to describe it here for quite a while, and now seems as good of time as any.&lt;/p&gt;&#xA;&lt;p&gt;The basic premise is: You have a service A with some data that other &amp;ldquo;consuming&amp;rdquo; services B, C, and D want to find out about.&#xA;Maybe the data is payments, maybe it&amp;rsquo;s support cases, maybe it&amp;rsquo;s password changes&amp;hellip; whatever.&#xA;The other services might include your data warehouse, some event listeners, whatever.&lt;/p&gt;</description>
    </item>
    <item>
      <title>osquery</title>
      <link>https://traviscj.com/blog/post/2018-01-12-osquery/</link>
      <pubDate>Fri, 12 Jan 2018 08:43:17 +0000</pubDate>
      <guid>https://traviscj.com/blog/post/2018-01-12-osquery/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve known about [osquery][] for a while, but recently spent some time digging around in it.&#xA;[osquery]: &lt;a href=&#34;https://osquery.io&#34;&gt;https://osquery.io&lt;/a&gt;&#xA;The basic idea is to provide a consistent SQL interface to a bunch of system data, instead of learning idiosyncrasies of individual commands (which themselves vary across operating systems).&#xA;My hacker buddy Sharvil has worked on osquery a fair bit and explained to me a couple years ago that it actually uses [sqlite][]&amp;rsquo;s [virtual table functionality][vtab] to provide the interface &amp;ndash; it&amp;rsquo;s a fascinating and brilliant project!&#xA;[sqlite]: &lt;a href=&#34;https://sqlite.org/&#34;&gt;https://sqlite.org/&lt;/a&gt;&#xA;[vtab]: &lt;a href=&#34;https://sqlite.org/vtab.html&#34;&gt;https://sqlite.org/vtab.html&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>relational java explorations with sqlite3 vtab</title>
      <link>https://traviscj.com/blog/post/2017-05-05-relational-java-explorations-with-sqlite3-vtab/</link>
      <pubDate>Fri, 05 May 2017 20:10:28 +0000</pubDate>
      <guid>https://traviscj.com/blog/post/2017-05-05-relational-java-explorations-with-sqlite3-vtab/</guid>
      <description>&lt;p&gt;One idea i have been mulling over lately is exposing a java codebase relationally, with queries like:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&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;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; classes &lt;span style=&#34;color:#66d9ef&#34;&gt;c&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;JOIN&lt;/span&gt; annotations a&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;ON&lt;/span&gt; a.class_id &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;c&lt;/span&gt;.id&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;WHERE&lt;/span&gt; a.name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;MyAnnotationClass&amp;#39;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;p&gt;The idea here is that you could search a codebase by pretending that you had tables for a whole bunch of things like:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;classes&lt;/li&gt;&#xA;&lt;li&gt;annotations&lt;/li&gt;&#xA;&lt;li&gt;variables&lt;/li&gt;&#xA;&lt;li&gt;literals&lt;/li&gt;&#xA;&lt;li&gt;methods&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;This would be a useful thing because instead of relying on an IDE like IntelliJ to do &amp;ldquo;find usages&amp;rdquo; operations, you could actually script those interactions.&#xA;Admittedly, of course, Java has some pretty sophisticated reflection APIs to find this sort of stuff too, but it seems like exploring the structure could be much easier writing Java code to traverse those trees.&lt;/p&gt;</description>
    </item>
    <item>
      <title>filter vs spec (draft)</title>
      <link>https://traviscj.com/blog/post/2017-01-18-filter_vs_spec/</link>
      <pubDate>Wed, 18 Jan 2017 00:00:00 +0000</pubDate>
      <guid>https://traviscj.com/blog/post/2017-01-18-filter_vs_spec/</guid>
      <description>&lt;p&gt;Consider a silly data model to store data about cities like&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;message City {&#xA;  optional string city_name = 1;&#xA;  optional string state = 2;&#xA;  optional int32 population = 3;&#xA;  optional int32 year_founded = 4;&#xA;  // ... presumably others :-)&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;and some sample data like:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;[&#xA;  {&amp;quot;city_name&amp;quot;: &amp;quot;Portland&amp;quot;, &amp;quot;state&amp;quot;: &amp;quot;OR&amp;quot;, &amp;quot;population&amp;quot;: ...},&#xA;  {&amp;quot;city_name&amp;quot;: &amp;quot;Portland&amp;quot;, &amp;quot;state&amp;quot;: &amp;quot;ME&amp;quot;, &amp;quot;population&amp;quot;: ...},&#xA;  {&amp;quot;city_name&amp;quot;: &amp;quot;Springfield&amp;quot;, &amp;quot;state&amp;quot;: &amp;quot;FL&amp;quot;, &amp;quot;population&amp;quot;: ...},&#xA;  {&amp;quot;city_name&amp;quot;: &amp;quot;Springfield&amp;quot;, &amp;quot;state&amp;quot;: &amp;quot;IL&amp;quot;, &amp;quot;population&amp;quot;: ...},&#xA;  {&amp;quot;city_name&amp;quot;: &amp;quot;Springfield&amp;quot;, &amp;quot;state&amp;quot;: &amp;quot;CO&amp;quot;, &amp;quot;population&amp;quot;: ...}&#xA;]&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;There are some useful entities we can define: (DRAFT NB: don&amp;rsquo;t read too much into the matcher vs filter lingo.)&lt;/p&gt;</description>
    </item>
    <item>
      <title>logging</title>
      <link>https://traviscj.com/blog/post/2014-09-26-logging/</link>
      <pubDate>Fri, 26 Sep 2014 00:00:00 +0000</pubDate>
      <guid>https://traviscj.com/blog/post/2014-09-26-logging/</guid>
      <description>&lt;p&gt;In grad school, I spent a lot of time writing code that read output from nonlinear optimization solvers, and tried&#xA;to do useful things with it.&#xA;A much better way to do that is called &amp;ldquo;structured logging&amp;rdquo;, an idea I experimented with a bit during grad school.&#xA;It has also been coming up in my working life, so I wanted to delve into it a bit deeper.&#xA;For a quick introduction, check out &lt;a href=&#34;http://gregoryszorc.com/blog/category/logging/&#34;&gt;Thoughts on Logging&lt;/a&gt;.&#xA;For a lot longer introduction, see &lt;a href=&#34;http://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying&#34;&gt;The Log: What every software engineer should know about real-time data unifying&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Quick MySQL Reference</title>
      <link>https://traviscj.com/blog/post/2009-05-27-a_quick_mysql_reference/</link>
      <pubDate>Wed, 27 May 2009 00:00:00 +0000</pubDate>
      <guid>https://traviscj.com/blog/post/2009-05-27-a_quick_mysql_reference/</guid>
      <description>&lt;p&gt;I got frustrated with not being able to write MySQL because I don&amp;rsquo;t do it often enough to be seeing it in my nightmares like MATLAB. But recently my datasets got annoyingly huge and it seemed like SQL might be a boon to me. So I set out to write a quick little program, and ended up writing this little reference along the way.&lt;/p&gt;&#xA;&lt;p&gt;Also, Sharvil Shah contributed some comments to it, so thanks to him for that!&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
