Where Relational Databases Just Fall a Bit Short

April 28th, 2010

database.jpg

Today I've run into a problem where I'm really not at all pleased with the solution I have. It works, but that's a far cry from what I want to see. It's best described as brute force, and that, while sometimes necessary, is almost never the words you'd use to describe an elegant solution. So here's the set-up:

I have volatility data for a series of instruments - OK, let's simplify it and make them options. We have the components of the option: underlying, expiration, strike, and then the "meat" of the data - the volatility. If I put this into a SQL table, it looks a lot like this:

  CREATE TABLE Volatility (
    acquired        datetime     NOT NULL,
    product         VARCHAR(42)  NOT NULL,
    expiration      datetime     NOT NULL,
    strike          FLOAT        NOT NULL,
    volatility      DOUBLE,
    generationTime  datetime,
    CONSTRAINT volatilityPK PRIMARY KEY (acquired, product, expiration, strike)
  )

where I added in the acquired field to hold when I received the data, and the generationTime to be the time the source sends me as the instant the data was generated there. It's pretty standard.

But I ran into a wrinkle. There were multiple sources sending me data for the same options so I was getting a bunch of primary key violations. That's not good, so the solution is to make the key unique by adding the 'source' as identified by the portfolio it's coming from. So now the table looks like this:

  CREATE TABLE Volatility (
    acquired        datetime     NOT NULL,
    portfolio       VARCHAR(128) NOT NULL,
    product         VARCHAR(42)  NOT NULL,
    expiration      datetime     NOT NULL,
    strike          FLOAT        NOT NULL,
    volatility      DOUBLE,
    generationTime  datetime,
    CONSTRAINT volatilityPK PRIMARY KEY (acquired, product, expiration, strike)
  )

But now we're getting to see the real problem: size. Let's look at a single record. In order to hold the "meat" of the table - the volatility, we need to have a primary key that's:

  • acquired - 8 bytes
  • portfolio - average of 8 bytes
  • product - average of 6 bytes
  • expiration - 8 bytes
  • strike - 4 bytes

for a total of approximately 34 bytes to hold an 8-byte volatility value. That's a ton of overhead.

The problem only gets worse when you look at the enormity of the data. I've got roughly 120,000 instruments and if I'm sampling them every 10 sec, that's 6 times a minute, 360 times an hour, or upwards of 3600 times a day. That's 432,000,000 rows a day or about 18,144,000,000 bytes for the data, of which a whopping 14,688,000,000 bytes is the key. That's almost 17GB of data a day - just to hold the volatility data.

If we held it in a 'map of maps' data structure, the only thing we'd need is the data that's actually changing: the acquired and volatility. That could represent a huge savings in memory. But the cost is that I can't "mirror" this data to a back-end SQL database, and can't use relational algebra to get data out.

I've thought of trying to duplicate this in SQL by having two tables:

  CREATE TABLE Instrument (
    instrumentID    IDENTITY     NOT NULL,
    portfolio       VARCHAR(128) NOT NULL,
    product         VARCHAR(42)  NOT NULL,
    expiration      datetime     NOT NULL,
    strike          FLOAT        NOT NULL,
    CONSTRAINT instrumentPK PRIMARY KEY (insrtumentID)
  )
 
  CREATE TABLE Volatility (
    acquired        datetime     NOT NULL,
    instrumentID    INTEGER      NOT NULL,
    volatility      DOUBLE,
    generationTime  datetime,
    CONSTRAINT volatilityPK PRIMARY KEY (acquired, product, expiration, strike)
  )

where I have a table of instruments, and those all have unique IDs, and then I'm using that ID, a simple integer, to represent the corresponding fields in the old Volatility table. It's all possible, and it's closer to the "normalized database" you'd expect to see, but the problem comes in when you look at the other factor: access speed.

If I'm generating 432 million rows a day, then it's not going to be too long before it's virtually impossible to do a join on that table. Even a month of data, and we're talking about holding years, would generate nearly 9 billion rows in that table.

Nah... there's no way we can do a SQL JOIN on that guy. We have to use the de-normalized data, and then just live with it. Crud. Not great, but it's the best I can do right now.

A Very Interesting Take on Ralph

April 28th, 2010

ChickenHawk.jpg

Today, one of the 'Old Guard' of The Shop stopped by to have a chat. He was stirred into action by one of the other developers in The Shop, as I'd told him that I was seriously considering leaving because of all the dysfunction in this place. I guess he felt that would be bad, and told his boss (the Old Guard Guy) to stop by and have a talk with me.

It was a very interesting talk.

It started out with the normal pleasantries, and then slowly moved into the region he wanted to probe: what's up with me. I liked his style. Nice, straight-forward, not smarmy - genuine. It was really nice.

When we got to my issues, I was reasonably articulate about them, especially about how, over this past year, I've tried to help move things towards a better technological footing, and at each and every turn, it's been made clear - sometimes painfully clear, that I was off base, and that I simply didn't understand the issues.

Oh... I understood the message. Loud and clear. Enough said.

Then we got to Ralph, and his take on Ralph was really exceptionally on point as well as funny. Ralph is the Chicken Hawk from Foghorn Leghorn cartoons. Yup... that's Ralph. He's all about action - even if it's not particularly well thought-out. In fact, "thought" is really not in his vocabulary. It's all about action and the appearance of superiority.

Amazingly funny. But sadly true.

I haven't had my last talk with this guy, we're going to talk next week. I have mixed feelings about this... part of me wants to stay and do the work I know I can do... but part of me thinks this place is not really ready for the tough choices that will have to be made to get there.

iTunes 9.1.1 is on Software Updates

April 28th, 2010

This morning I noticed that iTunes 9.1.1 was out on Software Updates and consisted primarily of some bug fixes for importing and a few other things. Nothing I've run into, but it's always nice to be prepared for the possible problem.

BBEdit 9.5 is Out

April 27th, 2010

As if Transmit 4 wasn't enough for one day, the Bare Bones crew released BBEdit 9.5 today with an impressive list of fixes and new features. What I like the most, however, is the "in-line" Find box that you can activate just like in Safari:

BKIRCProtocol.java

I've been wanting to have this feature in BBEdit for a long time. It's one of the most useful and clever additions to an editor I've seen. Up to now, it was in SubEthaEdit, which is nice, but still not to the point that it supplants BBEdit as my main code writing editor on the Mac.

There are a ton more things to explore in BBEdit 9.5, and I've only had it running for a few minutes, but it's just an incredible day for new software on the Mac. Amazing.

Dilbert and The Lost iPhone 4G – Hilarious

April 27th, 2010

OK, I'm a Dilbert fan, but in technology these days, who isn't? But yesterday's blog post by Scott Adams was just too funny. What's as funny is Scott's commentary about the situation. The fact that, like Doonesbury and Bloom County, the bet cartoons are the ones drawn from real life - with the absurdity built-in.

I giggled for quite a while on that... very funny.

Transmit 4.0 has been Released

April 27th, 2010

I'm a big fan of the software the Panic crew creates. In my opinion, it's a list of the very best in style, function, and usability for any platform - I'm just tickled pink it's for the Mac. Today they released Transmit 4, the latest update to their file transfer client, and Holy Cow! What an update!

Following their recent update to Unison, it makes sense that they do a completely new UI with much better features, much more usable screen real estate, and a few new GUI "extras" that make it a joy to watch working. Really. But what I didn't expect is the complete transformation of the "connected" GUI to be exactly what I've been wanting them to do: minimal footprint.

The new "connected" GUI looks wonderfully like a simple Finder window:

Transmit 4 - bobbeaty.com

I've been hoping for this for a very, very long time. It's wonderful.

The connection parameters are very easy to define - but that's no news. What is news in the engine is that they claim to have made it 25% faster than Transmit 3. That's something. Very nice.

One of the other nice features is the menu bar component that allows you to mount any of the connections as a disk in Finder. This means that you can have an SFTP site or WebDAV look like any other disk drive in the system and all the applications of that system see it as a disk drive. No need to have SFTP or WebDAV in any application - with this, it's all there for everyone. Amazingly cool!

I continue to believe that these guys create some of the very best software I've ever seen. Incredible.

Quietly Banging Away… Trying to Stay Hidden

April 26th, 2010

cubeLifeView.gif

Today was a day like a lot of the recent days have been: quiet... almost too quiet in the group. I think it has a lot to do with the "incident" as I've come to call it, and while I'm probably only partially right, my recent excursions at the end of the day and even the middle of the day, along with the number of closed-door meetings I've had with senior partners, probably make it pretty easy to put two and two together to see what's going on. It's not ideal by any means, but that issue is out there, what I've done in response is out there too, and we just have to deal with it.

I'm not really happy about the situation, but I'm not going to sit here and continue to deal with the kind of management issues I've had to deal with when there's a viable alternative out there. That's just silly. I'm not sure what's going to come of this, but it's going to change things, that's for sure.

So in the meantime, I'm doing my best to just do a bang-up job of getting new things done and old things fixed up. Heads-down coding. I get the obvious benefit that it's clear I'm still working for the good of the organization, while gaining the added benefit of staying in my little corner of the pod and not getting involved in too many conversations.

One thing I did get a little involved in was after I came in and caught up on my email, I vented a bit to my teammates about the things that transpired in my absence (on Friday). Basically, two things that I really, really wished hadn't happened:

  • I got called about memory additions to some machines - Why? they can do this. I'm not needed. I don't need to be called, emailed, texted just to be told they are adding memory to some boxes. It was my day off - which, it seems is simply something that doesn't exist for me in this place. I just needed to be home to help out Liza, and I got electronic "buckshot". Enough already.
  • Steve, a co-worker, pointed out jQuery to Ralph - this was the equivalent of giving Guy Fawkes C4 and remote-controlled detonators. It's going to run into a flurry of little, cosmetic, GUI changes to the web pages when we'd already looked at it, and decided that for the first round of this web system, it wasn't worth the effort. Clearly, we left Steve off the email list. My mistake.

Don't get me wrong, a JavaScript library like jQuery is nice, but there are a lot of libraries - some more focused on the UI components, some more all-encompassing like jQuery. Rather than just pick one, I wanted to have a really good idea about where we were headed with this web site and then look at what we needed help with for the second cut of the pages. Yeah, it's a lot of work, but not having put together a complete AJAX web app before, I had no idea what we needed, and didn't want to pick wrong.

So I had to say "Please don't do that. There's a reason we haven't, and now the monster is loose." Sure, it didn't do a bit of good, but I had to say it so that I can at least out a little bit of a lid on the situation. We have so many things that just don't work, or need to get working, that messing with pretty pop-ups and fades just doesn't really rise to the top of the TODO list.

Don't think it made any difference, but I had to voice my concerns on these issues because of all that's been building up in this cemetery of a pod - post-incident. It's just a big, long sigh...

Decided to Pick up Books on Groovy and Clojure

April 23rd, 2010

Given the way things have been heading at The Shop lately, I thought it would be a good idea to pick up a book on Groovy and another on Clojure. I didn't know nearly enough about them to be efficient and proficient with them, and I have a feeling that if things continue to develop as they have, I'll be needing them sooner, rather than later.

I have heard a little about Clojure, and it's an interesting take on solving the concurrency problem with software. I can see why it's popular, and it'll be interesting to see it in action, but Groovy was a complete mystery to me.

After the first few pages, I can see it's a Ruby-style of language with extensions to any and all objects. Looks interesting. I haven't done a lot with Ruby, and as Groovy is Java-based, it should work well into what I do. We'll have to see.

Anyway... picking up new tools is always fun.

Upgraded to Git 1.7.0.3 on MacBook Pro

April 22nd, 2010

gitLogo.gif

I was reading a few tweets from GitHub today and saw that they had a few new features that need Git 1.6.6+, and it got me to wondering: What version am I on, and what's the latest? I thought I was on 1.6.5.something, but I wasn't sure. So I decided to check. Simple enough.

Because I had tried the "build it yourself" for Mac OS X 10.3.9, I knew that with 10.5, I'd used the git-osx-installer that's hosted at Google Code. I looked there and saw that the 'current' version was 1.7.0.3, and I did a simple:

  $ git --version
  git version 1.6.5.2

OK... we have some work to do.

I got the package from Google Code, and then simply installed it. I'd done it before, so I didn't have to worry about the MANPATH and other things, I just needed to update it.

Now I get:

  $ git --version
  git version 1.7.0.3

and I can take advantage of the new features on GitHub.

I just need to remember to update my machines at home as well. Gotta do that tonight.

UPDATE: Interesting... according to the Git website, the "current" version is 1.7.0.5. That's OK, I'm a lot more current with 1.7.0.3 than 1.6.5.2.

Getting Spun Up Again

April 20th, 2010

Today the pod is still as quiet as a cemetery - primarily, I believe, because of the "issue" that occurred yesterday between my manager, Ralph, and myself, that I wrote about yesterday. Looking back at it, there was bound to come a time when we were going to have a clash like this. If he's convinced that he can code better than I can (and that was what this was really all about), then it was going to come up sooner or later. I'm glad it's out there, but it does tend to put a damper on the group dynamic for a while.

This morning I'm trying to get spun up and excited about being here, for as long as I'm here - or maybe as long as Ralph's my manager here, I'm open to all kinds of ideas now. Anyway, I'm doing some of the work Ralph asked me to do this month, and it was actually a little fun, which is great, as that's just what I needed.

Then I started updating the release notes for my web app and things dipped again.

One of the problems voiced by me as well as Ralph's managers is that he's asking me to build things that no one asks for. He's really doing speculative development, which isn't bad if it's small things like workflow changes, or helpful features, but when it's wholesale new data sets and features, it can cause problems. Such was the case this morning.

I have written a new component to the web app, and it's based on data that we can't possibly hold right now. We've had a database on order for months, memory on order for weeks, and it's taking a long time to get these things in house and installed. While I don't resent any of that, I do resent the idea that Ralph expects me to write the new features on hardware we don't have.

It's not really a compliment, it's an annoyance. It's arrogance on his part, because I'm telling him not to push, but he's saying "do it anyway". The result is, of course, that I'm doing the best I can, but on very limited data sets, so that when he looks at my work, it's all about "now switch it to this one... now this one..." in order to get the value without having to do his job of tracking down the acquisition of resources.

But I try to let that pass because, in the end, he's made my life easier for having made it clear I can't work with him long-term.

But when it rains, it pours.

His next brilliant idea is marketing.

He believes that we need to work to get more folks in The Shop using the application we have developed. Now technically, he agrees that the only customers we have are very satisfied with the work we've done, but that's not good enough. Still, if someone outside our customer group asks for something, I do my best to provide it to them. Again, that's not enough. His next goal is to get user who don't need our application to use it.

He wants is to market the application to internal users.

Now if this mattered to our group's existence, I'd say "OK, let's get out the mass-mailers", but it doesn't. In fact, Ralph has already been accused of doing too much with the platform by his managers. We have already gotten rave reviews by everyone, but still that's not enough.

I'm convinced it's about visibility and recognition. I can see that Ralph can't get enough of either, but I have no idea what happened in his past to make him this way. What I can say is that I'm all for new users using my stuff. I think that's great. But I've done marketing. I'll do some, but that's not what I'm going to want to do for several hours every week. I'd rather be talking to our real users and seeing if I can help them.

It's hard to get excited about your job when you're in a situation like this.