I would suggest using a specialized full-text indexing tool like Lucene for this. It will probably be easier to get up and running, and the result is faster and more featureful too. Postgres full text indexes will be useful if you also need structured search capability on top of this or transactionality of your search index is important.
If you do want to implement this in the database, something like the following scheme might work, assuming you use surrogate keys:
- for each searchable table create a view that has the primary key column of that table, the name of the table and a concatenation of all the searchable fields in that table.
- create a functional GIN or GiST index on the underlying over the to_tsvector() of the exact same concatenation.
- create a UNION ALL over all the views to create the searchable view.
After that you can do the searches like this:
SELECT id, table_name, ts_rank_cd(body, query) AS rank
FROM search_view, to_tsquery('search&words') query
WHERE query @@ body
ORDER BY rank DESC
LIMIT 10;