README
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:4k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. An attempt at some sort of Full Text Indexing for PostgreSQL.
  2. The included software is an attempt to add some sort of Full Text Indexing
  3. support to PostgreSQL. I mean by this that we can ask questions like:
  4. Give me all rows that have 'still' and 'nash' in the 'artist' field.
  5. Ofcourse we can write this as:
  6. select * from cds where artist ~* 'stills' and artist ~* 'nash';
  7. But this does not use any indices, and therefore, if your database
  8. gets very large, it will not have very high performance (the above query
  9. requires at least one sequential scan, it probably takes 2 due to the
  10. self-join).
  11. The approach used by this add-on is to define a trigger on the table and
  12. column you want to do this queries on. On every insert in the table, it
  13. takes the value in the specified column, breaks the text in this column
  14. up into pieces, and stores all sub-strings into another table, together
  15. with a reference to the row in the original table that contained this
  16. sub-string (it uses the oid of that row).
  17. By now creating an index over the 'fti-table', we can search for
  18. substrings that occur in the original table. By making a join between
  19. the fti-table and the orig-table, we can get the actual rows we want
  20. (this can also be done by using subselects, and maybe there're other
  21. ways too).
  22. The trigger code also allows an array called StopWords, that prevents
  23. certain words from being indexed.
  24. As an example we take the previous query, where we assume we have all
  25. sub-strings in the table 'cds-fti':
  26. select c.*
  27. from cds c, cds-fti f1, cds-fti f2
  28. where f1.string ~ '^stills' and
  29. f2.string ~ '^nash' and
  30. f1.id = c.oid and
  31. f2.id = c.oid ;
  32. We can use the ~ (case-sensitive regular expression) here, because of
  33. the way sub-strings are built: from right to left, ie. house -> 'se' +
  34. 'use' + 'ouse' + 'house'. If a ~ search starts with a ^ (match start of
  35. string), btree indices can be used by PostgreSQL.
  36. Now, how do we create the trigger that maintains the fti-table? First: the
  37. fti-table should have the following schema:
  38. create cds-fti ( string varchar(N), id oid );
  39. Don't change the *names* of the columns, the varchar() can in fact also
  40. be of text-type. If you do use varchar, make sure the largest possible
  41. sub-string will fit.
  42. The create the function that contains the trigger::
  43. create function fti() returns opaque as '/path/to/fti.so' language 'C';
  44. And finally define the trigger on the 'cds' table:
  45. create trigger cds-fti-trigger after update or insert or delete on cds
  46.     for each row execute procedure fti(cds-fti, artist);
  47. Here, the trigger will be defined on table 'cds', it will create
  48. sub-strings from the field 'artist', and it will place those sub-strings
  49. in the table 'cds-fti'.
  50. Now populate the table 'cds'. This will also populate the table 'cds-fti'.
  51. It's fastest to populate the table *before* you create the indices.
  52. Before you start using the system, you should at least have the following
  53. indices:
  54. create index cds-fti-idx on cds-fti (string, id);
  55. create index cds-oid-idx on cds (oid);
  56. To get the most performance out of this, you should have 'cds-fti'
  57. clustered on disk, ie. all rows with the same sub-strings should be
  58. close to each other. There are 3 ways of doing this:
  59. 1. After you have created the indices, execute 'cluster cds-fti-idx on cds-fti'.
  60. 2. Do a 'select * into tmp-table from cds-fti order by string' *before*
  61.    you create the indices, then 'drop table cds-fti' and
  62.    'alter table tmp-table rename to cds-fti'
  63. 3. *Before* creating indices, dump the contents of the cds-fti table using
  64.    'pg_dump -a -t cds-fti dbase-name', remove the connect
  65.    from the beginning and the . from the end, and sort it using the
  66.    UNIX 'sort' program, and reload the data.
  67. Method 1 is very slow, 2 a lot faster, and for very large tables, 3 is
  68. preferred.
  69. Maarten Boekhold <maartenb@dutepp0.et.tudelft.nl>