I have measured that in the past week. One of my websites has more than 500.000 user accounts. I picked the users who were not on the site in the last week, because they have already seen the news on the site, and got some 384.000+ distinct e-mail addresses. I needed to contact them regarding an important issue about the website. The e-mail was composed like this:
Hello,
you are reading this mail because you are a member of [mysite link].
Issue explained and link with [call to action]
Regards,
Your webmaster
[mysite link]
Links where not plain text, but special URLs I used to track the clicks.
I sent the e-mail slowely over a 7 day period. I wanted to track weekends and working days as well.
And here are the stats:
Hot spots in the e-mail message:
Here are the weekday stats:
I got an interesting problem today. I was supposed to check some HTML form before submitting to see if the text entered by the user in textarea has some specific words in it. Googling around I found a lot of stuff like “how to split text separated by commas” and such, but I simply wanted to extract words from a paragraph like this one.
My instinct was to use String.split() function, but it splits on a single character and I would have to write a recursive or iterative function to split on all non-word characters. Not being able to predict all the crap users can enter, this did not look like the right choice.
Luckily, I discovered String.match() which uses regex and is able to split text into an array of words, using something like this:
var arr = inputString.match(/\w+/g);
Cool, eh? Now, this all went fine for ASCII English text. But I need to work with UTF-8, or more specifically, Serbian language. Serbian Latin script used by my users has only 5 characters that are not from ASCII set, so I wrote a small replace function to replace those 5 with their closest matches. The final code looks like this:
var s = srb2lat(inputString.toUpperCase());
var a = s.match(/\w+/g);
for (var i = 0; a && i < a.length; i++)
{
if (a[i] == 'SPECIAL')
alert('Special word found!');
}
function srb2lat(str)
{
var len = str.length;
var res = '';
var rules = { 'Đ':'DJ', 'Ž':'Z', 'Ć':'C', 'Č':'C', 'Š':'S'};
for (var i = 0; i < len; i++)
{
var ch = str.substring(i, i+1);
if (rules[ch])
res += rules[ch];
else
res += ch;
}
return res;
}
";
If you use some other language, just replace the rules array with different transliteration rules.
Directly load your IDB file from Quicken Home Inventory on any 64 bit Windows system. It works on 32 bit as well, of course. Today, a new version of Attic Manager is released, version 3.00. This version is able to load data directly from IDB files, there is no need to install any additional software. You don’t even have to have Quicken installed. This also means that you can run this option on 64 bit Windows 7 for example, or even on Linux.
Attic Manager can also load the inventory data from QHI and MDF files. QHI files are also loaded without any additional software.
For MDF files you need to have Microsoft SQL Server Express Edition installed. This is a freeware from Microsoft that comes with QHIM, so if you already have Quicken installed on the same computer, you don’t need to install anything.
In any case, Attic Manager is now unique software on the market, being able to load all Quicken Home Inventory formats and allowing you to keep track of your items on any PC.
There are even hints of Mac version coming soon.
kerneldaemon494 asked: Why aren't you using InnoDB instead of MyISAM?
For this particular application, I simply cannot afford it. MyISAM is able to cache index and data separately, using it I can keep the whole index in RAM and website works great. I tried to convert to InnoDB, the result was 4x larger database and 20 times worse performance, mostly due to the fast that index and data gets the same priority for caching so it was killed by disk I/O. If this website was earning enough money to buy at least 4 x more RAM it might not be a bad idea. However, it this case I’d rather use Firebird - it has a similar memory footprint as InnoDB, but has much more features (*real* stored procedures and triggers that work without problems, ability to use table aliases in delete statements, database events functionality, better resistance to system crashes, etc.)
I have been using MySQL for a very intensive read-write web application (averaging 102 queries per second) for more than two years. I had ups and downs with it, like crazy MyISAM behavior that readers can block writers AND OTHER READERS. Basically, a table level lock is issued for read. I have 100+ records in a table, so it takes a while to find anything that is not indexed. In the meantime, users are pondering (102qps, remember) and load goes up so much because of web server processes queuing like crazy. Ok, I learned not to do that anymore. I now use binary logging, restore to a different server and query there. Maybe a switch to InnoDB would be a good idea, but in this case I’d rather use a serious MVCC database like Firebird. Why, you might ask… well, here’s one of many reasons, the one that prompted my to write this:
In Firebird, I can happily do this:
delete from atable a1
where exists (
select 1 from atable a2 where a1.data = a2.data and a1.id <> a2.id );
It just does it, and fast, because index on primary key field ID is used. In MySQL, to quote the manual:
“Currently, you cannot delete from a table and select from the same table in a subquery.”
Come on, this is one of the most basic database operation. So, what am I now to do? Waste my time dumping the list of IDs to delete to some temporary location, and then iterating that list to delete. :(
A few years ago I discovered screen, a nice Linux tool that enables you to detached from terminal with commands running and all in the background. You can even connect later from a different computer and continue where you left off. I initially used it for rtorrent, but now I also use it to administer remote computers, for example when I start to do something that might take more than a day, I can log back in tomorrow. Also loggin in from home/work to complete some task, etc. Another use is administering remote computers on dial-up (yes, there are some) or slow and unstable 3G connections. Even if connection breaks down, I can log in later and pick up where it stopped.
One of the annoying “problems” with screen is that shift+page up/down does not scroll the buffer. This is due to the fact that screen has its own buffers. To work with them you need to enter the “copy mode” using Ctrl+a followed by [. Since I use non-English keyboard that’s Ctrl+a, AltGr+f. Hard to remember when you don’t use it often.
I use Konsole, and I found a way to make it work by adding the following lines to .screenrc (in my home directory):
termcapinfo xterm|xterms|xs|rxvt ti@:te@
Beside being free (both as beer and also open source), you don’t need 24x7 DBA and there are generally less headaches. Here’s a nice example explained by Norman Dumbar in a mailing-list post. Norman administers over 600 Oracle databases and about 40 Firebird ones:
Oracle uses log files for REDO and has ROLLBACK_SEGMENTS or UNDO Segments (depending on Oracle version) for UNDO. It never uses log files for UNDO - and UNDO is what provides Read Consistency/MVCC in an Oracle database.
Changes are written to the LOG_BUFFER (n memory) and periodically - on commit, every 3 seconds max, or when the buffer is 33% full - flushed to the REDO logs. These REDO logs might be archived to disc when they fill up. That Depends on the database archive log mode though.
These logs are used when a database is restored and rolled forward (using the RECOVER DATABASE command, for example).
In order to roll back changes and to ensure read consistency, UNDO is used. These do live on disc - as tablespace files - but remain in memory in the buffer cache alongside data blocks etc.
When a SELECT is started, the data returned are the data from the data blocks. Each row in a block has an indicator that tells when it was last updated. If a pending update is taking place (currently uncommitted) or if a commit has taken place since this SELECT started then the data read from that data block has changed - and is not consistent with the start time of this SELECT transaction.
When this is detected, Oracle “rolls back” the changes to the start time of the SELECT taking place by looking for the UNDO block(s) associated with the transaction that made the changes. If that results in the correct (consistent) data, that’s what you get.
If it turns out that there were other transactions that also changed the data, they too will be detected and undone.
In this way you only ever see data that was consistent at the start of your own transaction.
As long as the DBA correctly sizes the UNDO tablespace and correctly sets the UNDO_RETENTION parameter to a decent enough value, data changes are able to be rolled back happily all the time.
If the DBA failed miserably in his/her duties, the ORA-01555 Snapshot too old” errors are the result. And are most irritating. Long running SELECTS - batch reports for example - tend to show up this error mostly.
Of course, you would never see such problems with Firebird, because the old record versions are stored in database and not the log files. You don’t have to care if system crashes - after reboot it simply works.
You might think that engineers who build Firebird are smarter than Oracle’s but sometimes I think Oracle is deliberately made so complicated to require DBA and also offer them job security. And also makes sure nobody can complain it’s too easy to use.
No, Quicken does not support 64bit Windows 7 yet. And there are no plans to do so. A few months back, GuacoSoft has released a new version of Attic Manager that is able to load data from Quicken directly. You can then export it into csv, excel, whatever OR simply use Attic Manager to manage the inventory.
Initial version of Attic Manager with this support (2.03) was only able to load data from .MDF files. However, a new version (2.50) is out now that supports .QHI files as well. It can load all data from .MDF. For files with .QHI extension, it loads all the data except image thumbnails. However, if you still keep your original images on the disk in same location where they were when you loaded them into QHIM, the Attic Manager will pick them up while importing and create thumbnails automatically. Not only that, but it will store a copy of each image into it’s database, so that you never lose it in the future.
So far, this is the only way to extract data from Quicken, and it’s really the only Home Inventory program on the market that enables you to transfer all your data before migrating to a new program.
Looking for a way to report a problem with YouTube software I found a link “Report a bug” a the bottom of the page. However, when I clicked it, I got redirected to:
http://www.google.com/tools/feedback/intl/en/error.html
Which says:
An error has occurred
We are sorry but we were not able to capture your feedback.