Self joining is a good thought. It is possible to write a query like this but handling n+ steps (A..B, A..B..C, A..B..C..n) is eventually going to make your query optimizer sh*t all over itself in all likeliness. You're not simply joining two tables but you also have a temporal relationship between each event. For example, if you're looking for users who performed events A then B then C, then you need to self join B to A making sure that all events in B are after A and then all events in C are after B.
Beyond that you have to worry about whether A, B and C are all within the same session. Trying to define a session such as "all events that occurred until there is 30 minutes of idle time" is going to be damn near impossible in the SQL query.
Couldn't a recursive query help here? Oracle has had CONNECT BY for years, and SQL Server has had recursive queries since 2005 (not sure about open source).
And, if SQL isn't the best way, what is? Map-reduce seems hellish to write to me, requiring very advanced developer skills - maybe some Python code?
Oracle's CONNECT BY is a good idea. I forgot about that. CONNECT BY is technically for hierarchical queries but you could probably hack something together between connect by and windowing in Oracle. I'd be curious to see how the performance is.
Part of my behavioral database is a query language for event data. It's called EQL (Event Query Language). I don't mean to slam SQL to try to make my solution sound better. I wrangled event data with SQL at a company years ago and it was awful. Data was denormalized and stored in rows but we ran into issues of max column lengths and row chaining not to mention a ton of custom processing.
I've also tried using Redis as an event store but you really need your data processing on the same box as the data to get good performance. For example, Redis supports ~100K calls per second (depending on the command used) on a single box. You can retrieve multiple events at one time but you're still going to hit a network performance and CPU bottleneck serializing all that data, not to mention that you still need to process it. I built my behavioral database to compile EQL to optimized machine code using LLVM and then iterating over events in memory-mapped data files. As a comparison, I'm traversing about 50 million events per core per second.
I'm not trying to knock RDBMS systems or Redis. I used to be an Oracle DBA and I've used Redis on plenty of projects. Behavioral data is just a different beast though. It needs fundamentally different tools.
Comments
Self joining is a good thought. It is possible to write a query like this but handling n+ steps (A..B, A..B..C, A..B..C..n) is eventually going to make your query optimizer sh*t all over itself in all likeliness. You're not simply joining two tables but you also have a temporal relationship between each event. For example, if you're looking for users who performed events A then B then C, then you need to self join B to A making sure that all events in B are after A and then all events in C are after B.
Beyond that you have to worry about whether A, B and C are all within the same session. Trying to define a session such as "all events that occurred until there is 30 minutes of idle time" is going to be damn near impossible in the SQL query.
Couldn't a recursive query help here? Oracle has had CONNECT BY for years, and SQL Server has had recursive queries since 2005 (not sure about open source).
And, if SQL isn't the best way, what is? Map-reduce seems hellish to write to me, requiring very advanced developer skills - maybe some Python code?
Oracle's CONNECT BY is a good idea. I forgot about that. CONNECT BY is technically for hierarchical queries but you could probably hack something together between connect by and windowing in Oracle. I'd be curious to see how the performance is.
Part of my behavioral database is a query language for event data. It's called EQL (Event Query Language). I don't mean to slam SQL to try to make my solution sound better. I wrangled event data with SQL at a company years ago and it was awful. Data was denormalized and stored in rows but we ran into issues of max column lengths and row chaining not to mention a ton of custom processing.
I've also tried using Redis as an event store but you really need your data processing on the same box as the data to get good performance. For example, Redis supports ~100K calls per second (depending on the command used) on a single box. You can retrieve multiple events at one time but you're still going to hit a network performance and CPU bottleneck serializing all that data, not to mention that you still need to process it. I built my behavioral database to compile EQL to optimized machine code using LLVM and then iterating over events in memory-mapped data files. As a comparison, I'm traversing about 50 million events per core per second.
I'm not trying to knock RDBMS systems or Redis. I used to be an Oracle DBA and I've used Redis on plenty of projects. Behavioral data is just a different beast though. It needs fundamentally different tools.