I don't really get why you don't want to use the fields API. A field only creates two tables with the default field storage module, the data and the revision table. And the revision table is only used when the entity it is attached to uses revisioning. And you can attach the same field to multiple entities. So I'm not sure what you mean with "lots more tables".
Creating a field is pretty simple, all you need to do is define the schema for your database table, the widget form and the formatter for displaying it. See http://api.drupal.org/api/examples/field_example--field_example.module/7.
That said, you can of course replicate the multiple value handling yourself (you can even do that and still use the field API), field_multiple_value_form() is the function that contains the generic implementation for fields, which you can adapt. It basically comes down to keep track of the number of "rows" you currently have and add that amount of form elements + a button do add one more.
Image/File fields for example implement their own multiple value handling (currently totally broken in D7 when you have multiple fields) and so does my own Dynamic Properties module.