2014-05-28 4 views

ответ

1

В Персистете нет поддержки первого класса/API для вторичных индексов. Это не значит, что вы не можете создавать индексы!

Что такое индекс? На практике весь индекс содержит другую копию данных. Например, в реляционной базе данных с таблицей users индекс в столбце first_name позволит эффективно искать по имени. Это может быть достигнуто путем хранения дополнительной копии первого имени с основным идентификатором для создания «ссылки» обратно в основную строку.

Вот единичный пример того, что:

import com.persistit.*; 
import com.persistit.exception.*; 
import java.io.*; 
import java.util.*; 

public class IndexDemo implements AutoCloseable 
{ 
    public static class User implements Serializable 
    { 
    public int id; 
    public String firstName; 
    public String lastName; 

    public User() { 
    } 

    public User(int id, String firstName, String lastName) { 
     this.id = id; 
     this.firstName = firstName; 
     this.lastName = lastName; 
    } 

    @Override 
    public String toString() { 
     return String.format("User(%d, %s, %s)", id, firstName, lastName); 
    } 
    } 

    private final Persistit db; 

    public IndexDemo() throws PersistitException { 
    Configuration c = new Configuration(); 
    c.getBufferPoolMap().get(16384).setCount(32); 
    c.getVolumeList().add(new VolumeSpecification(
     "IndexDemo.vol,create,pageSize:16384,initialPages:5,extensionPages:5,maximumPages:100" 
    )); 
    this.db = new Persistit(c); 
    } 

    @Override 
    public void close() throws PersistitException { 
    db.close(); 
    } 

    public Exchange userEx() throws PersistitException { 
    return db.getExchange("IndexDemo", "users", true); 
    } 

    public Exchange firstNamesEx() throws PersistitException { 
    return db.getExchange("IndexDemo", "firstNames", true); 
    } 

    // Save the user, both primary and secondary firstName index 
    public void saveUser(User u) throws PersistitException { 
    Exchange ex = userEx(); 
    // Primary entries: key of ID and value of full User 
    ex.getKey().append(u.id); 
    ex.getValue().put(u); 
    ex.store(); 
    // First name index: key of (name,ID) 
    ex = firstNamesEx(); 
    ex.append(u.firstName).append(u.id); 
    ex.store(); 
    } 

    // Look-up the user by ID 
    public User userByID(int id) throws PersistitException { 
    Exchange ex = userEx(); 
    // Construct and fetch our key 
    ex.getKey().append(id); 
    ex.fetch(); 
    // Careful: may not exist 
    if(!ex.getValue().isDefined()) { 
     return null; 
    } 
    // Otherwise get it from the value 
    return (User)ex.getValue().get(); 
    } 

    // Index scan for users with firstName, look-up and return all matches 
    public List<User> usersByFirstName(String firstName) throws PersistitException { 
    List<User> users = new ArrayList<>(); 
    Exchange ex = firstNamesEx(); 
    // Iterate over only entires matching firstName 
    ex.append(firstName).append(Key.BEFORE); 
    while(ex.next()) { 
     // Index to second component (id) and decode 
     int id = ex.getKey().indexTo(1).decodeInt(); 
     // And lookup the user 
     users.add(userByID(id)); 
    } 
    return users; 
    } 

    public static void main(String[] args) throws PersistitException { 
    try(final IndexDemo demo = new IndexDemo()) { 
     System.out.println("No Transaction:"); 
     runDemo(demo); 
    } 
    try(final IndexDemo demo = new IndexDemo()) { 
     System.out.println("Transaction:"); 
     demo.db.getTransaction().run(new TransactionRunnable() { 
     @Override 
     public void runTransaction() throws PersistitException { 
      runDemo(demo); 
     } 
     }); 
    } 
    } 

    public static void runDemo(IndexDemo demo) throws PersistitException { 
    demo.saveUser(new User(1, "John", "Doe")); 
    demo.saveUser(new User(2, "John", "Smith")); 
    demo.saveUser(new User(3, "Sally", "Jones")); 
    System.out.println(" User 1: " + demo.userByID(1)); 
    System.out.println(" User 10: " + demo.userByID(10)); 
    System.out.println(" Users named John:"); 
    for(User u : demo.usersByFirstName("John")) { 
     System.out.println(" " + u); 
    } 
    } 
} 

Запуск Урожайность этот вывод:

No Transaction: 
    User 1: User(1, John, Doe) 
    User 10: null 
    Users named John: 
    User(1, John, Doe) 
    User(2, John, Smith) 
Transaction: 
    User 1: User(1, John, Doe) 
    User 10: null 
    Users named John: 
    User(1, John, Doe) 
    User(2, John, Smith) 

Там не слишком много происходит:

  • пользователя POJO с несколькими атрибуты
  • Конфигурация и ввод в эксплуатацию Basic Persistit
  • Помощников для экономии, просмотровый первичным/ID и сканирования по имени
  • использования демонстрационного всех помощников
  • Main запускает демо как внутри, так и за ее пределами сделки

Все куски для создания чего-то чрезвычайно простого, как эта демонстрация, к чему-то очень сложному, как полный SQL-сервер.

+0

спасибо за быстрый ответ – bachr

+0

Интересно, если это влияет на производительность, поскольку индекс обновляется, в то же время обновляется запись. было бы лучше, если бы транзакции обновили индекс только тогда, когда все будет успешно выполнено? как тогда? – bachr

+1

У каждого индекса есть стоимость (т. Е. Больше работы во время записи/обновления), которая должна быть сопоставлена ​​с преимуществами (например, при заказе, поиске и индексировании только при чтении). Что касается задержки обслуживания индекса, возможно, этого не стоит. Одним из основных преимуществ транзакций является возможность полагаться на всю «работу», которая упаковывается вместе. – nathanlws