cache cache cache.
When you add items to the table, insert the cross references *then*. It will take (barely) longer to insert and make the db larger but it will save you time when doing searches.
The method for doing this efficiently would be to add an entry for *both* the nickname *and* the ip, as such...
(Note the ip and name can easily be stored in two *actual* tables, my example lists them side by side for convenience)
when "sam" enters with "1.2.3.4", add:
1.2.3.4 => sam
sam => 1.2.3.4
When "barry" enters with "1.2.3.4" followed by "2.3.4.5", the table will be:
1.2.3.4 => sam, barry
2.3.4.5 => barry
sam => 1.2.3.4
barry => 1.2.3.4, 2.3.4.5
You can then do lookups on the ip "1.2.3.4" to find sam and barry and then do lookups on sam, barry to get their other ips. You can even add caching for the names by doing a search on "barry"'s ips when he enters and then gathering the unique names for each ip (lookup 1.2.3.4, add "sam") *for all names involved*.. the new items would be added as:
!barry_names => barry, sam
!sam_names => sam, barry
Making the table
1.2.3.4 => sam, barry
2.3.4.5 => barry
sam => 1.2.3.4
barry => 1.2.3.4, 2.3.4.5
!barry_names => barry, sam
!sam_names => sam, barry
You would need to do more work to manage insertion and deletion-- but if you do more search lookups then insert/delete then your table will be optimized for search. There's plenty more cache based optimization you can do- each one slows down the insert time, so you'd have to strike a balance on insert/search speeds.
Hopefully this makes sense to you.
Using your data the table would be:
1.2.3.4 => sam, ryan
2.3.4.5 => sam, ryan
3.4.5.6 => sam
4.5.6.7 => sam, clark
4.4.4.4 => clark
0.0.0.0 => jeffrey
7.7.7.7 => bryan
sam => 1.2.3.4, 2.3.4.5, 3.4.5.6, 4.5.6.7
clark => 4.4.4.4, 4.5.6.7
jeffery => 0.0.0.0
ryan => 1.2.3.4, 2.3.4.5
bryan => 7.7.7.7
!sam_names => sam, ryan, clark
!clark_names => clark, sam
!jeffrey_names => jeffrey
!ryan_names => ryan, sam
!bryan_names => bryan