It’s really hard to find ski gear in the middle of summer…
REI sucks, not only is 90% of the clothing closeout, but there isn’t anything outside of rain gear to be found.
Found this on a old blog that I’m decommissioning — insight from an old WSJ article.
I’ve run into this problem a few times, but I’m putting out a call to see if anybody has some great insight into a good solution. To date, I’ve come up with three different approaches to handling user settings, but none of which I’m in love with. Other ideas, other comments, other ways?
Working assumptions
Small records only
First encountered this at Excite with Excite Mail, since we were using OpenWave as the backend we could store 255 bytes in one of their database tables, and it became a preferences store. Though of course it was a bit more restrive than the below SQL, it got the job done. With a bit of class wrapping ontop, it really works.
CREATE TABLE IF NOT EXISTS setting (
account_id int unsigned NOT NULL,
dkey varchar(20) NOT NULL,
data tinyblob NOT NULL,
created_on TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (account_id, dkey),
FOREIGN KEY (account_id) REFERENCES account(account_id) ON DELETE CASCADE
) ENGINE=InnoDB;
Small and Big records
Ok, so when you don’t want to deal with chaining of records you can create a BIG and SMALL store of data.
CREATE TABLE IF NOT EXISTS user_data (
user_id varchar(16) NOT NULL,
dkey varchar(20) NOT NULL,
dtype int DEFAULT 0,
data tinyblob,
created_on TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (user_id, dtype, dkey),
INDEX (user_id, dtype),
FOREIGN KEY (user_id) REFERENCES user(user_id) ON DELETE CASCADE
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS user_data_big (
user_id varchar(16) NOT NULL,
dkey varchar(20) NOT NULL,
dtype int DEFAULT 0,
data blob,
created_on TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (user_id, dtype, dkey),
INDEX (user_id, dtype),
FOREIGN KEY (user_id) REFERENCES user(user_id) ON DELETE CASCADE
) ENGINE=InnoDB;
Blob of doom
What about the idea that you don’t want your SQL store to have a clue, so save settings in one big blob (json, xml encoded, etc.)
CREATE TABLE IF NOT EXISTS user_blob (
user_id varchar(16) NOT NULL,
data blob,
created_on TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX (user_id),
FOREIGN KEY (user_id) REFERENCES user(user_id) ON DELETE CASCADE
) ENGINE=InnoDB;
Any other ideas? Cool suggestions, the magic solution I’ve forgotten?
I bike… I bike more than average… While a Poseur Jersey would be fun, I was thinking on my ride to work today that a shirt/jersey that said (primarily on my ride to work):
The more I bike
The less gas I use
The more there is
The cheaper it is
The happier you are
Maybe then a few cars would be a bit more considerate.
Tags: bicycle poetry
Way to carried away with this… here’s the SpiderMonkey version (as opposed to the rhino) one. Biggest complaint is the File object is a bit of a pain to use…
fd = File('p.test');
fd.open("read",'text');
mre = /^__MULTI_TOKEN__\s+(\S+)\s+(.*)\t?\s*(\d+)\s*$/;
sre = /^__SINGLE_TOKEN__\s+(\S+)\s*\t?\s*(\d+)\s*$/;
var ofd = File('full.txt');
ofd.open('write,create,replace','text');
first = {}
while (line = fd.readln()) {
if (m = line.match(mre)) {
first[m[1]] = (first[m[1]] ? first[m[1]] : 0) + parseInt(m[3]);
ofd.writeln(m[1] + " " + m[2] + "\t" + m[3]);
} else if (m = line.match(sre)) {
first[m[1]] = (first[m[1]] ? first[m[1]] : 0) + parseInt(m[2]);
} else {
print("Unknown: " + line);
}
}
ofd.close()
ofd = File('first.txt');
ofd.open('write,create,replace','text');
for (key in first) {
ofd.writeln(key + "\t" + first[key]);
}
ofd.close()
This is all based on the PHP/Perl/Python performance code.
Using the Rhino compiler… sorry no benchmark numbers, but just as a placeholder. To pick a nit, wanted to do first[m[1]] += parseInt(m[3]) but that yeilded a NaN since first[m[1]] was undefined… You would think that JavaScript would make undefined == 0.
fd = java.io.BufferedReader(java.io.FileReader('p.test'))
mre = /^__MULTI_TOKEN__\s+(\S+)\s+(.*)\t?\s*(\d+)\s*$/;
sre = /^__SINGLE_TOKEN__\s+(\S+)\s*\t?\s*(\d+)\s*$/;
ofd = java.io.PrintWriter(java.io.FileWriter('full.txt'));
first = {}
while (line = fd.readLine()) {
if (m = line.match(mre)) {
first[m[1]] = (first[m[1]] ? first[m[1]] : 0) + parseInt(m[3]);
ofd.println(m[1] + " " + m[2] + "\t" + m[3]);
} else if (m = line.match(sre)) {
first[m[1]] = (first[m[1]] ? first[m[1]] : 0) + parseInt(m[2]);
} else {
print("Unknown: " + line);
}
}
ofd.close()
ofd = java.io.PrintWriter(java.io.FileWriter('first.txt'));
// Sigh... rhino needs an update...
// first.forEach(function(e, i, a) { ofd.println(i + "\t" + e); });
for (key in first) {
ofd.println(key + "\t" + first[key]);
}
ofd.close()
This is all based on the PHP/Perl/Python performance code.