I admit I've given more attention on CPIR (because I think the sybil problem makes the IT assumptions not that useful), so I can't off the top of my head give you a concrete construction for a toy IT PIR that has good communications efficiency.
The thing I think you are probably missing most doesn't require you understand the PIR at that level of detail:
What PIR tools really give you is just an "oblivious array": An array of (e.g.) 100 byte entries of known size, and the PIR lets the client query any entry without the server(s) learning which entry the client queried.
From this alone you can construct your private "database": E.g. to do a prefix match you might require that the array be sorted and have the client perform a bisection search on the array using log(N) oblivious queries. Any database operation you can imagine can be constructed this way, but obviously they'll only be efficiency if they don't access to many cells.
While I don't recall what the concrete construction looks like for IT PIR, I can give a simple-ish (or at least from memory) example of a how a basic CPIR protocol is constructed using the the Goldwasser-Micali (GM) cryptosystem:
In this cryptosystem the public key is an RSA number (the product of two large primes). The main property of the GM cryptosystem is that if you know the private key (the factorization) you know the order of the multiplicative group mod P. And if you know the order, you can easily tell if a number is a quadratic residue (if it has a sqrt mod P) by computing the jacobi symbol which can be done with an exponentiation ladder or by using the extended euclidean algorithm. Under the assumption of the cryptosystem if you don't know the order you can't tell if a number is a QR or not.
GM is useful because if A=B*C (mod P) then QR(A) = QR(B) xor QR(C). So essentially it is a cryptosystem where I can give you encrypted values and you can apply an arbitrary set of XORs on them (and xors on the results of earlier xors) and also xor them with 1 (by squaring them) and then I can decrypt the result of your computation by using my private key to test the QR-ness of the result.
For discussion, we'll imagine that our private database is an array of 2^16 bits which you have and I want to query some particular bit without telling you which. You arrange the database into a 256x256 square array, and the bit I want to query is at position [i,j]. I pick 256 random numbers mod P such that all of them are quadratic residues, except for the one at position j, Lets call them: q_0 to q_255
I send you my public key P and these 256 q values. For each row you make a copy of the q values and square (mod P) the value when the bit in that cell is 0, then compute the product (mod P) of all the processed values for that row. At the end you have 256 values-- one for each row, you send them to me.
reply_row = product(data_(row,col) ? q_col : q_col^2)I ignore all but the i-th one, and then because I know the private key I can test if the value in question is a 0 by checking if it's a QR or not (because of the above mentioned: QR(A) = QR(B) xor QR(C)).
Now this version is inefficient in that you send me back 256 values, but I only pay attention to the i-th one. This inefficiency can be fixed by applying the scheme recursively (using the "reply" products as the table being queried).
Extending the scheme to more than 1-bit-per-cell is simple: You still send the same query, but apply it in parallel to as 1-bit-tables as your message has bits.
Main downside is doing all this mod P work (where P has to be big enough to make it unfactorable!) is slow, and also the queries are size sqrt(table_cells) (with the recursion the response can be as small as you like).