I have looked at your data and the book example, the problem is that there are three invalid polygons in data that are processed in the book:
GSHHS_l_L1.shp
ID = 92-W
POLYGON ((-180.0 71.514793999999995,-179.69008299999999 71.577888999999999,-178.648889 71.577416999999997,-178.40644399999999 71.549916999999994,-177.406306 71.244167000000004,-177.877444 71.022889000000006,-179.500111 70.863749999999996,-179.93011100000001 70.979583000000005,-180.0 70.962072000000006))
ID = 486-W
POLYGON ((-180.0 -16.799126,-179.84419399999999 -16.691278,-179.80041700000001 -16.789193999999998,-179.850472 -16.878361000000002,-180.0 -16.959561))
GSHHS_l_L2.shp
ID = 7333-W
POLYGON ((-180.0 65.393473,-179.76583299999999 65.428332999999995,-179.95416700000001 65.385555999999994,-179.90972199999999 65.316389,-180.0 65.321635))
Because this is an example it would be easiest to delete those polygons from the dataset or just add one if statement in you code
if geometry.IsValid():
cursor.execute("INSERT INTO gshhs (level, geom) VALUES (%s, ST_GeomFromText(%s, 4326))", (level, wkt))
If you don't need third party support and don't forsee the need to query by type keeping them in the same table works just fine. Alternatively you could use an inheritance model as discussed in chapter 3 of PostGIS in Action.
http://www.postgis.us/chapter_03_edition_1
From an architecture perspective PostGIS doesn't really care if in a query multiple different types are used. If it performed fine for you in Oracle it will be just as if not better performant in PostGIS.
There are 2 reasons to split it up (and either can be done later as needed):
1) Prevent people from inserting different types you don't want like geometry collections, circular strings and what not (which you could just manually define a constraint)
2) If you have a billion points and 1000 polygons, and do a lot of point in polygon tests, the speed is much better if when you query and do your join -- its against a billion -- to 1000 record table as opposed to a billion to billion record table. This would be the case for any spatial database I think (not specific to PostGIS). It's true for all relational queries I would guess too (not specific to spatial queries).
Best Answer
You can query it with Find_SRID. So if your table looks something like:
then use: